受以泪洗面的影响看了一遍Y86 Pipeline的HCL代码+简单注释 很象HDL的行为级描述

发布于 2022-09-18 22:53:41 字数 16691 浏览 26 评论 0

####HCL Description of Control for Pipelined Y86 Processor    ##
####Coryright (C) Randal E. Bryant, David R. O'Hallaron, 2002 ##

###C Iinclude's. Don't alter these
###C头文件,不要修改
quote 'include <stdio.h>'
quote 'include "isa.h"'
quote 'include "pipeline.h"'
quote 'include "stages.h"'
quote 'include "sim.h"'
quote 'int sim_main(int argc, char *argv[]);'
quote 'int main(int argc, char *argv[]){return sim_main(argc, argv);}'

###Declarations. Do not change/remove/delete any of these
###声明,不要做任何改动

###Symbolic representation of Y86 Instruction Codes
###Y86的指令表示
intsig INOP        'I_NOP'                #空操作
intsig IHALT        'I_HALT'        #停机
intsig IRRMOVL        'I_RRMOVL'        #寄存器-寄存器移动
intsig IIRMOVL        'I_IRMOVL'        #立即数-寄存器移动
intsig IRMMOVL        'I_RMMOVL'        #寄存器-内存移动
intsig IMRMOVL        'I_MRMOVL'        #内存-寄存器移动
intsig IOPL        'I_ALU'                #ALU操作
intsig IJXX        'I_JUMP'        #跳转
intsig ICALL        'I_CALL'        #调用
intsig IRET        'I_RET'                #返回
intsig IPUSHL        'I_PUSHL'        #入栈
intsig IPOPL        'I_POPL'        #出栈

###Symbolic representation of Y86 Registers referenced explicitly
###Y86的寄存器表示
intsig RESP        'REG_ESP'        #栈指针寄存器
intsig RNONE        'REG_NONE'        #"无寄存器"的保留值

#ALU Functions referenced explicitly
#ALU功能操作表示
intsig ALUADD        'A_ADD'                #ALU加法

###Signals that can be referenced by control logic
###被控制逻辑使用的信号

##Pipeline Regsiter F
##F(Fetch 取指阶段)的寄存器流水线
intsig F_predPC        'pc_curr->pc'        #PC的预设值

#Intermediate Values in Fetch Stage
#取指阶段的中间表示(IR?
intsig f_icode        'if_id_next->icode'        #取指令的代码
intsig f_ifun        'if_id_next->ifun'        #取指令的函数
intsig f_valC        'if_id_next->valc'        #被取指令的常数数据(数据表示,比如000表示halt)
intsig f_valP        'if_id_next->valp'        #下一条指令的地址

##Pipeline Register D
##D(Decode 解码阶段)的寄存器流水线
intsig D_icode        'if_id_curr->icode'        #指令码
intsig D_rA        'if_id_curr->ra'        #指令的rA域
intsig D_rB        'if_id_curr->rb'        #指令的rB域
intsig D_valP        'if_id_curr->valp'        #PC自加,就是下一个指令的地址

#Intermediate Values in Decode Stage
#解码阶段的内部表示
intsig d_srcA        'id_ex_next->srca'        #指令解码中的srcA(操作数A)
intsig d_srcB        'id_ex_next->srcb'        #指令解码中的srcB
intsig d_rvalA        'd_regvala'                #从寄存器中读出的valA(变量A)
intsig d_rvalB        'd_regvalb'                #从寄存器中读出的valB

##Pipeline Register E
##E(Execute 执行阶段)的寄存器流水线
intsig E_icode        'id_ex_curr->icode'        #指令码
intsig E_ifun        'id_ex_curr->ifun'        #指令函数
intsig E_valC        'id_ex_curr->valc'        #常量
intsig E_srcA        'id_ex_curr->srca'        #源操作数A寄存器ID(放在哪个寄存器中)
intsig E_valA        'id_ex_curr->vala'        #操作数A的值
intsig E_srcB        'id_ex_curr->srcb'        #源操作数B的寄存器ID
intsig E_valB        'id_ex_curr->valb'        #操作数B的值
intsig E_dstE        'id_ex_curr->deste'        #目的操作数E的寄存器ID
intsig E_dstM        'id_ex_curr->destm'        #目的操作数M的寄存器ID

#Intermediate Values in Execute Stage
#执行阶段的内部表示
intsig e_vslE        'ex_mem_next->vale'        #ALU计算出valE
boolsig e_Bch        'ex_mem_next->takebranch'        #要分支吗?

##Pipeline Register M
##M(Mem 访存阶段)的寄存器流水线
intsig E_dstM        'ex_mem_curr->icode'        #指令码
intsig E_dstM        'ex_mem_curr->ifun'        #指令函数
intsig E_dstM        'ex_mem_curr->vala'        #源操作数A的值
intsig E_dstM        'ex_mem_curr->deste'        #目的操作数D的寄存器ID
intsig E_dstM        'ex_mem_curr->vale'        #ALU计算出的E值
intsig E_dstM        'ex_mem_curr->destm'        #目的操作数M的寄存器ID
boolsig M_Bch        'ex_mem_curr->takebranch'        #分支标志

#Intermediate Values in Memory Stage
#访存阶段的内部表示
intsig m_valM        'mem_wb_next->valme'        #valM要写回内存

##Pipeline Register W
##W(Write Back 写回阶段)的寄存器流水线
intsig W_icode        'mem_wb_curr->icode'        #指令码
intsig W_dstE        'mem_wb_curr->deste'        #目的操作数E的寄存器ID
intsig W_valE        'mem_wb_curr->vale'        #ALU计算出的E值
intsig W_dstM        'mem_wb_curr->destm'        #目的操作数M的寄存器ID
intsig W_valM        'mem_wb_curr->valm'        #内存操作数M的值

###Control Signal Definitions
###控制信号定义

##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;
];

#Does fetched instruction require a regid byte?
#取得的指令需要寄存器ID吗?
bool need_regids =
        f_icode in { IRRMOVL, IOPL, IPUSHL, IPOPL,
                        IIRMOVL, IRMMOVL, IMRMOVL };
#Does fetched instruction require a constant word?
#取得的指令需要常数吗?
bool need_valC =
        f_icode in { IIRMOVL, IRMMOVL, IMRMOVL, IJXX, ICALL };

bool instr_valid = f_icode in
                { INOP, IHALT, IRRMOVL, IIRMOVL, IRMMOVL, IMRMOVL,
                        IOPL, IJXX, ICALL, IRET, IPUSHL, IPOPL };

#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;        #使用从寄存器中读出的值
];

int new_E_valB = [
        d_srcB == E_dstE : e_valE;        #valE将会被exeute阶段使用
        d_srcB == M_dstM : m_valM;        #valE将会被memory阶段使用
        d_srcB == M_dstE : M_valE;        #valE将会被memory阶段使用
        d_srcB == W_dstM : W_valM;        #valE将会被write back阶段使用
        d_srcB == W_dstE : W_valE;        #valE将会被write back阶段使用
        1 : d_rvalB;        #使用从寄存器中读出的值
];

##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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

傾旎 2022-09-25 22:53:41

有流水线的了单周期就没怎么看,设计CPU的话也不知道HCL行不行,还没见过这种硬件设计语言的编译器,也不知道怎么综合。了解的人来说说

香草可樂 2022-09-25 22:53:41

我对这种语言也不了解,只是在CS:APP中见过。不知这种语言为何人所创,也不知现在还有没有人使用。只记得按照书中的介绍,貌似有人用它来写模拟器。

滥情稳全场 2022-09-25 22:53:41

我还是继续Verilog吧。感觉HCL设计CPU有点不太靠谱。
c版还想设计软核不?我现在想设计一个类MIPS的,用于教学目的。以后发展到多核和多线程,设计好了再综合到FPGA验证(那些东西没怎么碰过,都不懂 )。

风为裳 2022-09-25 22:53:41

软核设计是一定要设计的,大致的架构我想好了,不可能设计非常复杂的,因为考虑到大家并不是做这个的。另外我觉得此时设计,还不如不设计,因为很多人对verilog和硬件行为并不是非常清楚,硬件和软件之间的差别太大了,拿着软件的思维去设计硬件那么必然会失败。真正的设计,至少等到我先找好工作吧,现在我也不太有心情。准备辞职换工作,但简历还在书写中,想找的公司、工作还没彻底想好。MIPS有个很大的问题,那就是编译器都没做好的类MIPS那不能叫类MIPS。

旧情勿念 2022-09-25 22:53:41

我对llvm比较熟悉,移植llvm没什么障碍,想到时候移植BSD上去练练手。
对软件和硬件不一样,我只想从逻辑上验证设计是正确的,至于毛刺什么都没想。只是对IPL有个想法,想试试。

涫野音 2022-09-25 22:53:41

没工具,没编译,可能有地方抄错了。

固执像三岁 2022-09-25 22:53:41

本版的兄弟们谁有Linux下IC设计软件的lisence给我一个吧,什么软件都行。
我下了一个 Xilinx ISE WebPACK,没ID号,没法装,注册的时候发给我的mail有,我给删了。谁有可以用的给我一个,谢谢。

蒗幽 2022-09-25 22:53:41

Cadence NC-Sim for linux
够专业

清风不识月 2022-09-25 22:53:41

我那个610的lic不行,NC-Verilog一堆错误

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文