##Fetch Stage
##取指阶段
#What address should instruction be fetched at
#应该从什么地方取指
int f_pc = [
#Mispredicted branch. Fetch at incremented PC
#无预测分支。取值时增加PC。
M_icode == IJXX && !M_Bch : M_valA;
#Completion of RET instruction
#RET返回指令
W_icode == IRET : W_valM;
#Default : Use predicted value of PC
#缺省使用PC的预设值
1 : F_predPC;
];
#Predict next value of PC
#预取下一个PC值
int new_F_predPC = [
f_icode in { IJXX, ICALL } : f_valC;
1 : f_valP;
];
##Decode Stage
##解码阶段
#What register should be used as the A source?
#哪些寄存器可以被源操作数A使用
int new_E_srcA = [
D_icode in { IRRMOVL, IRMMOVL, IOPL, IPUSHL } : D_rA;
D_icode in { IPOPL, IRET } : RESP;
1 : RNONE; #Don't need register 不需要寄存器
];
#What register should be used as the B source?
#哪些寄存器可以被源操作数B使用
int new_E_srcB = [
D_icode in { IOPL, IRMMOVL, IMRMOVL } : D_rB;
D_icode in { IPUSHL, IPOPL, ICALL, IRET } : RESP;
1 : RNONE; #Don't need register 不需要寄存器
];
#What register should be used as the E destination?
#哪些寄存器可以被目的操作数E使用
int new_E_dstE = [
D_icode in { IRRMOVL, IIRMOVL, IOPL } : D_rB;
D_icode in { IPUSHL, IPOPL, ICALL, IRET } : RESP;
1 : RNONE; #Don't need register 不需要寄存器
];
#What register should be used as the M destination?
#哪些寄存器可以被目的操作数M使用
int new_E_dstM = [
D_icode in { IMRMOVL, IOPL } : D_rA;
1 : RNONE; #Don't need register 不需要寄存器
];
#What should be the A value?
#操作数A的值应该是什么?
#Forward into decode stage for valA
#valA进入decode的下一阶段将会怎样
int new_E_valA = [
D_icode in { ICALL, IJXX } : D_valP; #Use incremented PC 使用增加后的PC
d_srcA == E_dstE : e_valE; #valE将会被exeute阶段使用
d_srcA == M_dstM : m_valM; #valE将会被memory阶段使用
d_srcA == M_dstE : M_valE; #valE将会被memory阶段使用
d_srcA == W_dstM : W_valM; #valE将会被write back阶段使用
d_srcA == W_dstE : W_valE; #valE将会被write back阶段使用
1 : d_rvalA; #使用从寄存器中读出的值
];
##Execute Stage
##执行阶段
#Select input A to ALU
#ALU的输入A
int aluA = [
E_icode in { IRRMOVL, IOPL } : E_valA;
E_icode in { IIRMOVL, IRMMOVL, IMRMOVL } : E_valC;
E_icode in { ICALL, IPUSHL } : -4;
E_icode in { IRET, IPOPL } : 4;
#Other instructions don't need ALU
];
#Select input B to ALU
int aluB = [
E_icode in { IRMMOVL, IMRMOVL, IOPL, ICALL,
IPUSHL, IRET, IPOPL } : E_valB;
E_icode in { IRRMOVL, IIRMOVL } : 0;
#Other instructions don't need ALU
];
#Set the ALU function
#设置ALU功能
int alufun = [
E_icode == IOPL : E_ifun;
1 : ALUADD;
];
##Memory Stage
##访存阶段
#Select memory address
int mem_addr = [
M_icode in { IRMMOVL, IPUSHL, ICALL, IMRMOVL } : M_valE;
M_icode in { IPOPL, IRET } : M_valA;
#Other instructions don't need address
];
#Set read control signal
#设置读控制信号
bool mem_read = M_icode in { IMRMOVL, IPOPL, IRET };
#Set write control signal
bool mem_write = M_icode in { IRMMOVL, IPUSHL, ICALL };
###Pipeline Register Control
###寄存器流水线控制
#Should I stall or inject a bubble into Pipeline Register F?
#我是不是应该在F寄存器流水线中插入'气泡'?
#At most one of these can be true.
#大多数情况下是的。
bool F_bubble = 0;
bool F_stall =
#Condition for a load/use Hazard
#load/use冲突的条件
E_icode in { IMRMOVL, IPOPL } &&
E_dstM in { d_srcA, d_srcB } ||
#Stalling at fetch while ret passes through pipeline
#在ret通过流水线时插入一个取指
IRET in { D_icode, E_icode, M_icode };
#Should I stall or inject a bubble into Pipeline Register D?
#我是不是应该在D寄存器流水线中插入'气泡'?
#At most one of these can be true.
#大多数情况下是的。
bool D_stall =
#Condition for a load/use Hazard
#满足load/use冲突的条件的话
E_icode in { IMRMOVL, IPOPL } &&
E_dstM in { d_srcA, d_srcB };
bool D_bubble =
#Mispredicted branch
#非预测分支
(E_icode == IJXX && !e_Bch) ||
#Stalling at fetch while ret passes through pipeline
#在ret通过流水线时插入一个取指
IRET in { D_icode, E_icode, M_icode };
#Should I stall or inject a bubble into Pipeline Register E?
#我是不是应该在F寄存器流水线中插入'气泡'?
#At most one of these can be true.
#大多数情况下是的。
bool E_stall = 0;
bool E_bubble =
#Mispredicted branch
#非预测分支
(E_icode == IJXX && !e_Bch) ||
#Condition for a load/use Hazard
#满足load/use冲突的条件的话
E_icode in { IMRMOVL, IPOPL } &&
E_dstM in { d_srcA, d_srcB };
#Should I stall or inject a bubble into Pipeline Register M?
#我是不是应该在F寄存器流水线中插入'气泡'?
#At most one of these can be true.
#大多数情况下是的。
bool M_stall = 0;
bool M_bubble =0;作者: prolj 时间: 2008-05-11 15:01
有流水线的了单周期就没怎么看,设计CPU的话也不知道HCL行不行,还没见过这种硬件设计语言的编译器,也不知道怎么综合。了解的人来说说作者: cjaizss 时间: 2008-05-11 15:10
我对这种语言也不了解,只是在CS:APP中见过。不知这种语言为何人所创,也不知现在还有没有人使用。只记得按照书中的介绍,貌似有人用它来写模拟器。作者: prolj 时间: 2008-05-11 15:24
我还是继续Verilog吧。感觉HCL设计CPU有点不太靠谱。
c版还想设计软核不?我现在想设计一个类MIPS的,用于教学目的。以后发展到多核和多线程,设计好了再综合到FPGA验证(那些东西没怎么碰过,都不懂 )。作者: cjaizss 时间: 2008-05-11 15:34 软核设计是一定要设计的,大致的架构我想好了,不可能设计非常复杂的,因为考虑到大家并不是做这个的。另外我觉得此时设计,还不如不设计,因为很多人对verilog和硬件行为并不是非常清楚,硬件和软件之间的差别太大了,拿着软件的思维去设计硬件那么必然会失败。真正的设计,至少等到我先找好工作吧,现在我也不太有心情。准备辞职换工作,但简历还在书写中,想找的公司、工作还没彻底想好。MIPS有个很大的问题,那就是编译器都没做好的类MIPS那不能叫类MIPS。作者: prolj 时间: 2008-05-11 15:39
我对llvm比较熟悉,移植llvm没什么障碍,想到时候移植BSD上去练练手。
对软件和硬件不一样,我只想从逻辑上验证设计是正确的,至于毛刺什么都没想。只是对IPL有个想法,想试试。作者: prolj 时间: 2008-05-13 14:04 标题: 我从书上抄的Verilog行为级描述,可以对比一下 没工具,没编译,可能有地方抄错了。