verlog简单CPU设计
简单处理器设计
处理器的指令集
数据计算操作指令
| 指令 | 操作数1 | 操作数2 | 操作数3 | 操作 |
|---|---|---|---|---|
| NOP | 等待 | |||
| HALT | 停机 | |||
| LOAD | r1 | r2 | val3 | gr[r1] <-m[r2+val3] |
| STORE | r1 | r2 | val3 | m[r2+val3] <-r1 |
| MUL | r1 | r2 | r3 | r1 <-r2 * r3 |
| ADD | r1 | r2 | r3 | r1 <-r2+r3 |
| ADDI | r1 | val2 | val3 | r1 <-r1+{val2,val3} |
| ADDC | r1 | r2 | r3 | r1 <-r2+r3+CF |
| SUB | ||||
| SUBI | ||||
| SUBC | ||||
| CMP | r2 | r3 | r2-r3 : set CF,ZF,NF |
逻辑运算
| 指令 | 操作数1 | 操作数2 | 操作数3 | 操作 |
|---|---|---|---|---|
| AND | r1 | r2 | r3 | r1 <- r2 & r3 |
| OR | ||||
| XOR | ||||
| SLL | r1 | r2 | val3 | 逻辑左移r1 <- r2 <<val3 |
| SRL | r1 | r2 | val3 | |
| SLA | r1 | r2 | val3 | 算数左移r1 <- r2 <<val3 |
| SRA | r1 | r2 | val3 |
跳转指令
| 指令 | 操作数1 | 操作数2 | 操作数3 | 操作 |
|---|---|---|---|---|
| JUMP | val2 | val3 | 跳转到{val2,val3} | |
| JMPR | r1 | val2 | val3 | 跳转到r1+{val2,val3} |
| BZ | r1 | val2 | val3 | ZF=1 跳转 r1+{val2+val3} |
| BNZ | r1 | val2 | val3 | ZF=0… |
| BN | NF=1 | |||
| BNN | ||||
| BC | CF=1 | |||
| BNC |
注:BZ(branch zf)当zf为真则跳过,其余BN,BC同理
顶层设计模块

总设计框架如上,由五层流水级构成,分别是IF(取指令阶段),ID(指令译码阶段),EX(执行指令阶段),MEM(访存取数),WB(结果写回),实现表示数据流向,虚线表示控制指令如何控制处理器运行。主体部分分别是,指令内存模块,通用寄存器,以及数据内存模块。
冒险现象
指令只有在执行到EX阶段才会得出结果,结果到了MEM阶段才会写回寄存器,到了WB阶段才会写回内存,在流水线CPU中,往往会出现前面的指令还未执行完成将结果写回寄存器,后面的指令就需要读取该寄存器的值来进行执行,那就出现了相关现象。在处理器工作过程中也需要注意该现象发发生。
处理器的工作状态
处理器一共有两个工作状态分别为:idle(闲置状态)、exec(工作状态)。
处理器在这两个状态之间切换。

代码部分
top顶层模块设计
主要是模块拼接在一起,在此不过多赘述。
xxxxxxxxxxmodule CPU( input clk, input enable, //使能 input reset, input start, input button, output [15:0] light, output [7:0] en );
wire PCPU_clk; wire MEM_clk; wire LIGHT_clk; wire [15:0] d_datain; wire [15:0] i_datain; wire [3:0] select_y; wire [7:0] d_addr; wire [15:0] d_dataout; wire d_we; wire [7:0] i_addr; wire [31:0] y; //分频得到内存模块clk clk_div getMEMclk( .orgin_clk(clk), .reset(reset), .div(16'b0100_0000_0000_0000), .div_clk(MEM_clk) ); //分频得到显示模块clk clk_div getLIGHTclk( .orgin_clk(clk), .reset(reset), .div(16'b0010_0000_0000_0000), .div_clk(LIGHT_clk) ); PCPUcontroller PCPUctrl( .myclk(clk), .button(button), .reset(reset), .sense(PCPU_clk) //输出PCPU的工作clk ); PCPU pcpu( .clock(PCPU_clk), .enable(enable), .reset(reset), .start(start), .d_datain(d_datain), .i_datain(i_datain), //输入操作指令 .d_addr(d_addr), .d_dataout(d_dataout), .d_we(d_we), .i_addr(i_addr), .y(y) ); I_mem i_mem( .mem_clk(MEM_clk), .addr(i_addr), .rdata(i_datain) ); D_mem d_mem( .mem_clk(MEM_clk), .dwe(d_we), .addr(d_addr), .wdata(d_dataout), .rdata(d_datain) ); light_show show_light_1( .light_clk(LIGHT_clk), .reset(reset), .y(y[31:16]), .light(light[15:8]), .en(en[7:4]) );
light_show show_light_2( .light_clk(LIGHT_clk), .reset(reset), .y(y[15:0]), .light(light[7:0]), .en(en[3:0]) );endmodule
分频模块
将系统时钟分频得到整体系统不同部分的控制时钟,主要有三个时钟,显示模块时钟,输入模块时钟,以及工作时钟,此处分频只针对上述前两种时钟。
module clk_div( input orgin_clk, input reset, input [15:0] div, output reg div_clk ); reg [15:0] count; always@(posedge orgin_clk or posedge reset) begin if(reset) begin div_clk < 0; count < 0; end else begin if(count div) begin div_clk < div_clk; count < 0; end else count < count 1'b1; end end
endmodule
处理器工作频率
这里实现该图中的状态机。

Stop状态和Inc指令运行状态,当按下Botton时则输出信号,此处Trap为防抖装置,当安置时间过长时也不会多次触发,而是进入循环状态。
xxxxxxxxxxmodule PCPUcontroller( input myclk, input button, input reset, output reg sense );
parameter STOP 2'b00, INC 2'b01, TRAP 2'b10; //读取指令状态, reg [1:0] state, nextstate; always@(posedge myclk or posedge reset) begin if(reset) state < STOP; else state < nextstate; end always@() begin case(state) STOP: if(button) nextstate < INC; else nextstate < STOP; INC: nextstate < TRAP; TRAP: if(button) nextstate < TRAP; else nextstate < STOP; default: nextstate < STOP; //按下一次按钮无论多久只会输出一次sense,trap状态实现消抖 endcase end always@() begin if(reset) sense < 0; else case(state) INC: sense < 1'b1; default: sense < 1'b0; endcase end
endmodule
显示模块
这里用于七段数码管显示
xxxxxxxxxxmodule light_show( input light_clk, input reset, input [15:0] y, output reg [7:0] light, output reg [3:0] en );
reg [1:0] dp; reg [3:0] four;
always@(posedge light_clk or posedge reset) begin if(reset) dp < 0; else begin dp < dp 1'b1; end end always@() begin if(reset) begin four < 0; en < 0; end else begin case(dp) 0: begin four < y[3:0]; en < 4'b0001; end 1: begin four < y[7:4]; en < 4'b0010; end 2: begin four < y[11:8]; en < 4'b0100; end 3: begin four < y[15:12]; en < 4'b1000; end default: begin four < 0; en < 0; end endcase end end always@() begin if(reset) begin light < 8'b00000000; end else begin case(four) 0: light < 8'b11111100; 1: light < 8'b01100000; 2: light < 8'b11011010; 3: light < 8'b11110010; 4: light < 8'b01100110; 5: light < 8'b10110110; 6: light < 8'b10111110; 7: light < 8'b11100000; 8: light < 8'b11111110; 9: light < 8'b11110110; 4'b1010: light < 8'b11101110; //A 4'b1011: light < 8'b00111110; //b 4'b1100: light < 8'b10011100; //C 4'b1101: light < 8'b01111010; //d 4'b1110: light < 8'b10011110; //E 4'b1111: light < 8'b11001110; //P default: light < 8'b11111100; endcase end end
endmodule
数据存储
该部分主要由256个8位宽寄存器组成,用于存储数据,其中dwe是使能端,当使能端为1才能存取数。
module D_mem( input mem_clk, input dwe, input [7:0] addr, input [15:0] wdata, output wire [15:0] rdata ); reg [15:0] d_mem [255:0]; //内存宽度16位,深度256 ---2^8 assign rdata d_mem[addr]; always@(posedge mem_clk) begin if(dwe) //使能 d_mem[addr] < wdata; end
endmodule
指令内存
在该模块存放预设的指令,之后运行将按照该指令顺序运行
x
module I_mem( input mem_clk, input [7:0] addr, output wire [15:0] rdata );
parameter idle1'b0;parameter exec1'b1;parameter NOP5'b00000;parameter HALT5'b00001;parameter LOAD5'b00010;parameter STORE5'b00011;parameter MUL5'b10000;parameter ADD5'b01000;parameter ADDI5'b01001;parameter ADDC5'b10001;parameter CMP5'b01100;
parameter AND5'b01101;parameter SLL5'b00100;parameter SLA5'b00101;
parameter JUMP5'b11000;parameter JMPR5'b11001;parameter BZ5'b11010;parameter BNZ5'b11011;parameter BN5'b11100;parameter BC5'b11110;
parameter SUB5'b01010;parameter SUBI5'b01011;parameter SUBC5'b10010;parameter OR5'b01110;parameter XOR5'b01111;parameter SRL5'b00110;parameter SRA5'b00111;parameter BNN5'b11101;parameter BNC5'b11111;
parameter gr03'b000;parameter gr13'b001;parameter gr23'b010;parameter gr33'b011;
reg [15:0] i_mem [255:0]; assign rdata i_mem[addr]; always@(posedge mem_clk) begin case(addr) 0: i_mem[addr] < {ADDI, gr1, 4'b1010, 4'b1011}; //gr1=00AB 1: i_mem[addr] < {ADDI, gr2, 4'b0011, 4'b1100}; //gr2=003C 2: i_mem[addr] < {ADD, gr3, 1'b0, gr1, 1'b0, gr2};//gr3=3CAB 3: i_mem[addr] < {STORE, gr3, 1'b0, gr0, 4'b0000};// 4: i_mem[addr] < {ADDI, gr1, 4'b0000, 4'b0011}; //gr1=0003 5: i_mem[addr] < {ADDI, gr2, 4'b0000, 4'b0010}; //gr2=0002 6: i_mem[addr] < {MUL, gr3,1'b0, gr1, 1'b0, gr2};//gr3=0006 7: i_mem[addr] < {STORE, gr3, 1'b0, gr0, 4'b0001}; 8: i_mem[addr] < {LOAD, gr1, 1'b0, gr0, 4'b0000}; 9: i_mem[addr] < {LOAD, gr2, 1'b0, gr0, 4'b0001}; 10: i_mem[addr] < {ADD, gr3, 1'b0, gr1, 1'b0, gr2}; 11: i_mem[addr] < {STORE, gr3, 1'b0, gr0, 4'b0001}; 12: i_mem[addr] < {JUMP, 4'b0000, 4'b0010, 4'b1000}; 13: i_mem[addr] < {ADDI, gr1, 4'b1010, 4'b1011}; 40: i_mem[addr] < {HALT, 11'b000_0000_0000}; default: i_mem[addr] < {NOP, 11'b000_0000_0000}; endcase end
endmodule
核心部件
在该部分中主要完成各部分的连接以及功能阐述。
首先实现工作与闲置状态转换

IF阶段
这里出现冒险现象的第一种情况,当前周期无法获取寄存器的值,读取的时候还在计算,读取数还在计算,没进行到WB写回阶段

接着是跳转指令因为影响PC计数,所以单列

ID阶段
根据不同的指令,从通用寄存器中取出相应的值出来作运算或者存储到Data Memory中,如果为Branch指令且标志位为true则需要Flush掉当前内容;否则如果冲突出现,则需要根据不同的运算指令从不同的地方取出内容。
冒险现象
读写竞争冒险,同时设计对于内存的修改,一方面数据安全问题,另一方面BUS同时间只能服务于一组数据


对于跳转或者操作数有非地址的A寄存器情况

对于B寄存器

EX阶段
对于有运算标志的运算,置相应的zf与nf值

ALU计算模块
在此处写入命令

上述涉及到的乘法模块,采用移位乘法器。
MEM模块

WB模块

最后是显示

核心部分整体代码如下:
xxxxxxxxxxmodule PCPU( input clock, input enable, input reset, input start, input [15:0] d_datain, input [15:0] i_datain, output wire [7:0] d_addr, output wire [15:0] d_dataout, output wire d_we, output wire [7:0] i_addr, output reg [31:0] y );
parameter idle1'b0;parameter exec1'b1;parameter NOP5'b00000; //空操作parameter HALT5'b00001; //停机parameter LOAD5'b00010; //加载parameter STORE5'b00011; //存储parameter MUL5'b10000; //r1 <- r2 * r3parameter ADD5'b01000; //r1 <- r2 + r3parameter ADDI5'b01001; //r1 <- r1 + {r2,r3}parameter ADDC5'b10001; //r1 <- r2 + r3 + CFparameter CMP5'b01100; // r2-r3 设置 CF,ZF,NF
parameter AND5'b01101; // ¶meter SLL5'b00100; //逻辑左移parameter SLA5'b00101; //算数左移parameter SRL5'b00110; //逻辑右移parameter SRA5'b00111; //算术右移
parameter JUMP5'b11000; //跳转{r2,r3}parameter JMPR5'b11001; //跳转到 r1+{r2,r3}parameter BZ5'b11010; //如果 ZF=1 跳转到r1+{r2,r3}parameter BNZ5'b11011; //如果 ZF=0 跳转到r1+{r2,r3}parameter BN5'b11100; //如果 NF=1 跳转到r1+{r2,r3}parameter BNN5'b11101; //如果 NF=0 跳转到r1+{r2,r3}parameter BC5'b11110; //如果 CF=1 跳转到r1+{r2,r3}parameter BNC5'b11111; //如果 CF=0 跳转到r1+{r2,r3}
parameter SUB5'b01010; parameter SUBI5'b01011;parameter SUBC5'b10010;parameter OR5'b01110; // 或parameter XOR5'b01111; //异或
parameter gr03'b000;parameter gr13'b001;parameter gr23'b010;parameter gr33'b011;
reg state; reg [7:0] pc; reg [15:0] id_ir; reg [15:0] ex_ir, reg_A, reg_B, smdr; reg [15:0] mem_ir, reg_C, smdr1; reg dw; reg flag; reg [15:0] ALUo;reg zf, nf, cf; reg [15:0] wb_ir, reg_C1; reg [15:0] gr[0:7]; //数据内存中八个寄存器 assign d_dataout smdr1; assign d_we dw; assign d_addr reg_C[7:0]; assign i_addr pc; reg cf_temp; wire [16:0]mul_temp; //带进位 /*******CPUcontrol**********************/ reg nextstate; //CPU的状态 always@(posedge clock or posedge reset) begin if(reset) state < idle; else state < nextstate; end always@() begin case(state) idle: if((enable 1'b1) (start 1'b1)) nextstate < exec; else nextstate < idle; exec: if((enable 1'b0) (wb_ir[15:11] HALT)) nextstate < idle; else nextstate < exec; endcase end /***************************************/ /****************IF*********************/ //每一个上升沿从Instruction Memory中根据地址pc取出一条指令, always@(posedge clock or posedge reset) //LOAD指令需要根据不同的指令从当前CPU运算中特定位置读取; begin //Branch指令及其标志位为true则Flush掉一条指令;跳转指令则直接跳转并处理pc值延后一个周期的情况, if(reset) //其余情况直接读取下一条指令 begin id_ir < 16'b0000_0000_0000_0000; pc < 8'b0000_0000; end else if(state exec) begin /*************Hazard*******************/ //当前周期无法获取寄存器的值,读取的时候还在计算 if((id_ir[15:11] LOAD) //hazard第一种情况,读取数还在计算,没进行到WB写回阶段 (i_datain[15:11] ADD) ((id_ir[10:8] i_datain[7:4]) (id_ir[10:8] i_datain[3:0]))) begin id_ir < 16'bxxxx_xxxx_xxxx_xxxx; pc < pc; end /**************************************/ else begin id_ir < i_datain; if(((mem_ir[15:11] BZ) (zf 1'b1)) //zf为0 //zf 结果为零 zf=1 ((mem_ir[15:11] BN) (nf 1'b1)) // nf为1 //nf 最高位 ((mem_ir[15:11] BC) (cf 1'b1)) // cf=1有进位 //cf 进位标志 ((mem_ir[15:11] BNZ) (zf 1'b0)) ((mem_ir[15:11] BNN) (nf 1'b0)) ((mem_ir[15:11] BNZ) (cf 1'b0))) //根据ALU标志以及指令决定PC的值 pc < reg_C[7:0]; else if((mem_ir[15:11] JUMP) (mem_ir[15:11] JMPR)) pc < reg_C[7:0]; else pc < pc 1'b1; end end else //处于闲置状态 begin pc < pc; id_ir < id_ir; end end /***************************************/ /****************ID*********************/ //根据不同的指令,从通用寄存器中取出相应的值出来作运算或者存储到Data Memory中; always@(posedge clock or posedge reset) //如果为Branch指令且标志位为true则需要Flush掉当前内容;否则如果冲突出现, begin //则需要根据不同的运算指令从不同的地方取出内容 if(reset) begin ex_ir < 16'b0000_0000_0000_0000; reg_A < 16'b0000_0000_0000_0000; reg_B < 16'b0000_0000_0000_0000; smdr < 16'b0000_0000_0000_0000; end else if(state exec) begin ex_ir < id_ir; if(id_ir[15:11] STORE) //for Hazard Mode smdr < ALUo; //写入数据 /********************reg_A***********************/ /********************Hazard**********************/ //读写竞争冒险,同时设计对于内存的修改 if(wb_ir[15:11] LOAD id_ir[7:4] wb_ir[10:8]) //一方面数据安全问题,另一方面BUS同时间只能服务于一组数据 reg_A < reg_C1; else if(mem_ir[15:11] LOAD id_ir[7:4] mem_ir[10:8]) reg_A < d_datain; else if(ex_ir[15:11] LOAD id_ir[7:4] ex_ir[10:8]) reg_A < ALUo; else if(mem_ir[15:11] LOAD id_ir[7:4] mem_ir[10:8]) reg_A < reg_C; else if(wb_ir[15:11] LOAD id_ir[7:4] wb_ir[10:8]) reg_A < reg_C1; else begin //非竞争情况但是涉及跳转或有非地址操作数 /***********************************************/ if((id_ir[15:11] BZ) (id_ir[15:11] BN) (id_ir[15:11] JMPR) (id_ir[15:11] BC) (id_ir[15:11] BNZ) (id_ir[15:11] BNN) (id_ir[15:11] BNC) (id_ir[15:11] ADDI) (id_ir[15:11] SUBI)) reg_A < gr[(id_ir[10:8])]; else reg_A < gr[(id_ir[6:4])]; end /********************reg_B**********************/ /********************Hazard*********************/ if(wb_ir[15:11] LOAD id_ir[3:0] wb_ir[10:8]) reg_B < reg_C1; else if(mem_ir[15:11] LOAD id_ir[3:0] mem_ir[10:8]) reg_B < d_datain; else if(ex_ir[15:11] LOAD id_ir[3:0] ex_ir[10:8]) reg_B < ALUo; else if(mem_ir[15:11] LOAD id_ir[3:0] mem_ir[10:8]) reg_B < reg_C; else if(wb_ir[15:11] LOAD id_ir[3:0] wb_ir[10:8]) reg_B < reg_C1; else begin /***********************************************/ if((id_ir[15:11] LOAD) (id_ir[15:11] SLL) (id_ir[15:11] SLA) (id_ir[15:11] SRL) (id_ir[15:11] SRA)) reg_B < {12'b0000_0000_0000, id_ir[3:0]}; else if((id_ir[15:11] BZ) (id_ir[15:11] BN) (id_ir[15:11] JUMP) (id_ir[15:11] JMPR) (id_ir[15:11] BC) (id_ir[15:11] BNZ) (id_ir[15:11] BNN) (id_ir[15:11] BNC) (id_ir[15:11] ADDI)) reg_B < {8'b0000_0000, id_ir[7:0]}; else if((id_ir[15:11] STORE)) begin reg_B < {12'b0000_0000_0000, id_ir[3:0]}; end else reg_B < gr[id_ir[2:0]]; end end else //非工作状态, state==idle begin ex_ir < ex_ir; reg_A < reg_A; reg_B < reg_B; smdr < smdr; end end /***************************************/ /****************EX*********************/ always@(posedge clock or posedge reset) begin if(reset) begin mem_ir < 16'b0000_0000_0000_0000; reg_C < 16'b0000_0000_0000_0000; smdr1 < 16'b0000_0000_0000_0000; zf < 1'b0; nf < 1'b0; cf < 1'b0; dw < 1'b0; end else if(state exec) begin mem_ir < ex_ir; reg_C < ALUo; cf < cf_temp; if((ex_ir[15:11] ADD) (ex_ir[15:11] CMP) (ex_ir[15:11] ADDI) (ex_ir[15:11] SUB) (ex_ir[15:11] SUBI) (ex_ir[15:11] MUL) (ex_ir[15:11] SLL) (ex_ir[15:11] SRL) (ex_ir[15:11] SLA) (ex_ir[15:11] SRA) (ex_ir[15:11] ADDC) (ex_ir[15:11] SUBC)) begin //操作指令是计算或逻辑运算指令时,给计算标志nf,zf赋对应值 if(ALUo 16'b0000_0000_0000_0000) zf < 1'b1; else zf < 1'b0; if(ALUo[15] 1'b1) nf < 1'b1; else nf < 1'b0; end else if(ex_ir[15:11] STORE) //写入数据 begin dw < 1'b1; smdr1 < smdr; end end else //闲置状态 idle begin reg_C < reg_C; smdr1 < smdr1; dw < dw; end end MULTIPLY multiply(.a(reg_A),.b(reg_B),.c(mul_temp)); /****************ALU********************/ always@() begin if(state exec) begin if(reset) begin ALUo < 16'b0000_0000_0000_0000; cf_temp < 0; end else case(ex_ir[15:11]) NOP: {cf_temp, ALUo} < {cf_temp, ALUo}; HALT: {cf_temp, ALUo} < {cf_temp, ALUo}; AND: {cf_temp, ALUo} < {cf_temp, reg_A reg_B}; OR: {cf_temp, ALUo} < {cf_temp, reg_A reg_B}; XOR: {cf_temp, ALUo} < {cf_temp, reg_A reg_B}; SLL: {cf_temp, ALUo} < {cf_temp, reg_A << reg_B}; SRL: {cf_temp, ALUo} < {cf_temp, reg_A >> reg_B}; SLA: {cf_temp, ALUo} < {cf_temp, reg_A <<< reg_B}; SRA: {cf_temp, ALUo} < {cf_temp, reg_A >>> reg_B}; JUMP: {cf_temp, ALUo} < {cf_temp, reg_B}; MUL: {cf_temp, ALUo} < mul_temp; ADD: {cf_temp, ALUo} < {1'b0 reg_A} {1'b0 reg_B}; ADDI: {cf_temp, ALUo} < {1'b0 reg_A} {1'b0 reg_B}; ADDC: {cf_temp, ALUo} < {1'b0 reg_A} {1'b0 reg_B} cf; SUB: {cf_temp, ALUo} < {1'b0 reg_A} {1'b0 reg_B}; SUBI: {cf_temp, ALUo} < {1'b0 reg_A} {1'b0 reg_B}; SUBC: {cf_temp, ALUo} < {1'b0 reg_A} {1'b0 reg_B} cf; CMP: {cf_temp, ALUo} < {1'b0 reg_A} {1'b0 reg_B}; LOAD: begin ALUo < reg_A reg_B; cf_temp < cf_temp; end STORE: begin ALUo < reg_A reg_B; cf_temp < cf_temp; end JMPR: begin ALUo < reg_A reg_B; cf_temp < cf_temp; end BZ: begin ALUo < reg_A reg_B; cf_temp < cf_temp; end BNZ: begin ALUo < reg_A reg_B; cf_temp < cf_temp; end BN: begin ALUo < reg_A reg_B; cf_temp < cf_temp; end BNN: begin ALUo < reg_A reg_B; cf_temp < cf_temp; end BC: begin ALUo < reg_A reg_B; cf_temp < cf_temp; end BNC: begin ALUo < reg_A reg_B; cf_temp < cf_temp; end default:{cf_temp, ALUo} < {cf_temp, ALUo}; endcase end end /***************************************/ /***************MEM*********************/ always@(posedge clock or posedge reset) begin if(reset) begin reg_C1 < 16'b0000_0000_0000_0000; wb_ir < 16'b0000_0000_0000_0000; end else if(state exec) begin wb_ir < mem_ir; if(mem_ir[15:11] LOAD) reg_C1 < d_datain; else reg_C1 < reg_C; end end /***************************************/ /****************WB********************/ always@(posedge clock or posedge reset) begin if(reset) begin gr[0] < 16'b0000_0000_0000_0000; gr[1] < 16'b0000_0000_0000_0000; gr[2] < 16'b0000_0000_0000_0000; gr[3] < 16'b0000_0000_0000_0000; gr[4] < 16'b0000_0000_0000_0000; gr[5] < 16'b0000_0000_0000_0000; gr[6] < 16'b0000_0000_0000_0000; gr[7] < 16'b0000_0000_0000_0000; end else if(state exec) begin if((wb_ir[15:11] LOAD) (wb_ir[15:11] ADD) (wb_ir[15:11] ADDI) (wb_ir[15:11] ADDC) (wb_ir[15:11] SUB) (wb_ir[15:11] SUBI) (wb_ir[15:11] SUBC) (wb_ir[15:11] AND) (wb_ir[15:11] OR) (wb_ir[15:11] XOR) (wb_ir[15:11] SLL) (wb_ir[15:11] SRL) (wb_ir[15:11] SLA) (wb_ir[15:11] SRA) (wb_ir[15:11] MUL)) gr[wb_ir[10:8]] < reg_C1; end else begin end end /***************************************/ /**************show*****************/ always@() begin y < {8'b1111_1100,pc,reg_C}; end /***************************************/endmodule
在看代码写代码的时候有很多想法,但是正真写blog时又不知道要写些什么了,等之后又有想法了再继续加好了。