继续来~~~~~~~~~~~~~~~~~~~~~~
【读书笔记】RISC存储程序机的电路设计(1)
【读书笔记】RISC存储程序机的电路设计(2)
【读书笔记】RISC存储程序机的电路设计(3)
【读书笔记】RISC存储程序机的电路设计(4)
【读书笔记】RISC存储程序机的电路设计(5)
【读书笔记】RISC存储程序机的电路设计(6)
图放好~~~~~~~~~~~~~~~~~~~~~~
我这个顺序说实话没有太掌握好,应该在前面就把Processor的代码贴全的,不过没关系,经过前面的完整分析,我们已经直接拼出来Processor的代码啦,进而得到全部编码。
所有需要的子模块代码:
`ifndef PROC_UNIT
`define PROC_UNITmodule reg_unit #(`include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output reg [WORD_WD -1:0] data_out,input [WORD_WD -1:0] data_in,input load, clk, rst_n
);always &#64;(posedge clk)beginif(rst_n &#61;&#61; 1&#39;b0)begindata_out <&#61; {WORD_WD{1&#39;b0}};endelse if(load &#61;&#61; 1&#39;b1)beginif(DISPLAY_EN &#61;&#61; 1) $display("%0t, %m, data_out update to &#39;b%8b(&#39;h%2h-&#39;d%0d)", $realtime, data_in, data_in, data_in);data_out <&#61; data_in;endelse begindata_out <&#61; data_out;endendendmodule//: reg_unitmodule program_count #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output reg [WORD_WD -1:0] count_out,input [WORD_WD -1:0] count_in,input load, incr, clk, rst_n
);always &#64;(posedge clk)beginif(rst_n &#61;&#61; 1&#39;b0)begincount_out <&#61; {WORD_WD{1&#39;b0}};endelse if(load &#61;&#61; 1&#39;b1)begincount_out <&#61; count_in;endelse if(incr &#61;&#61; 1&#39;b1)begincount_out <&#61; count_out &#43; &#39;h1;endelse begincount_out <&#61; count_out;endendendmodule//: program_countmodule mux_5sel1 #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output reg [WORD_WD -1:0] mux_out,input [WORD_WD -1:0] mux_in0, mux_in1, mux_in2, mux_in3, mux_in4,input [SEL1_WD -1:0] sel
);always &#64;(*)begincase(sel)&#39;h0: mux_out &#61; mux_in0;&#39;h1: mux_out &#61; mux_in1;&#39;h2: mux_out &#61; mux_in2;&#39;h3: mux_out &#61; mux_in3;&#39;h4: mux_out &#61; mux_in4;default: mux_out &#61; {WORD_WD{1&#39;bx}};endcase endendmodule//: mux_5sel1module mux_3sel1 #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output reg [WORD_WD -1:0] mux_out,input [WORD_WD -1:0] mux_in0, mux_in1, mux_in2,input [SEL2_WD -1:0] sel
);always &#64;(*)begincase(sel)&#39;h0: mux_out &#61; mux_in0;&#39;h1: mux_out &#61; mux_in1;&#39;h2: mux_out &#61; mux_in2;default: mux_out &#61; {WORD_WD{1&#39;bx}};endcase endendmodule//: mux_3sel1module alu_unit #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output reg [WORD_WD -1:0] alu_out,output zero_flag,input [WORD_WD -1:0] alu_in1, alu_in2,input [OPCODE_WD -1:0] opcode
);always &#64;(*)begincase(opcode)NOP: alu_out &#61; &#39;h0;ADD: alu_out &#61; alu_in2 &#43; alu_in1;SUB: alu_out &#61; alu_in2 - alu_in1; AND: alu_out &#61; alu_in2 & alu_in1;NOT: alu_out &#61; ~alu_in2;default:alu_out &#61; &#39;hx;endcaseendassign zero_flag &#61; ~(|alu_out);endmodule//: alu_unit
&#96;endif
&#96;ifndef PROCESSING_UNIT
&#96;define PROCESSING_UNITmodule processing_unit #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output [WORD_WD -1:0] instruction ,//to ctloutput zero_flag ,//to ctloutput [ADDR_WD -1:0] addr ,//to mem, addressoutput [WORD_WD -1:0] bus1 ,//to mem, data_ininput [WORD_WD -1:0] mem_word ,//from mem, data_outinput load_R0, load_R1, load_R2, load_R3,input load_PC, input load_IR,input load_reg_Y,input load_reg_Z,input load_add_R,input inc_PC,input [SEL1_WD -1:0] mux1_sel_to_bus1,input [SEL2_WD -1:0] mux2_sel_to_bus2,input clk, rst_n
);wire [WORD_WD -1:0] bus2;wire [WORD_WD -1:0] R0_out, R1_out, R2_out, R3_out;wire [WORD_WD -1:0] alu_out;wire [WORD_WD -1:0] Y_out;wire [WORD_WD -1:0] PC_out;wire alu_zero_flag; wire [OPCODE_WD -1:0] opcode;assign opcode &#61; instruction[(WORD_WD -1) : (WORD_WD -OPCODE_WD)];reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_R0(.data_out(R0_out), .data_in(bus2), .load(load_R0), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_R1(.data_out(R1_out), .data_in(bus2), .load(load_R1), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_R2(.data_out(R2_out), .data_in(bus2), .load(load_R2), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_R3(.data_out(R3_out), .data_in(bus2), .load(load_R3), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_REG_Y(.data_out(Y_out), .data_in(bus2), .load(load_reg_Y), .clk(clk), .rst_n(rst_n)); reg_unit #(.WORD_WD(1)) U_REG_Z(.data_out(zero_flag), .data_in(alu_zero_flag), .load(load_reg_Z), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_IR(.data_out(instruction), .data_in(bus2), .load(load_IR), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_ADD_R(.data_out(addr), .data_in(bus2), .load(load_add_R), .clk(clk), .rst_n(rst_n));program_count #(.WORD_WD(WORD_WD)) U_PC(.count_out(PC_out), .count_in(bus2), .load(load_PC), .incr(inc_PC), .clk(clk), .rst_n(rst_n));mux_5sel1 #(.WORD_WD(WORD_WD), .SEL1_WD(SEL1_WD)) U_MUX1(.mux_out(bus1), .mux_in0(R0_out), .mux_in1(R1_out), .mux_in2(R2_out), .mux_in3(R3_out),.mux_in4(PC_out),.sel(mux1_sel_to_bus1));mux_3sel1 #(.WORD_WD(WORD_WD), .SEL1_WD(SEL2_WD)) U_MUX2(.mux_out(bus2), .mux_in0(alu_out), .mux_in1(bus1), .mux_in2(mem_word), .sel(mux2_sel_to_bus2));alu_unit #(.WORD_WD(WORD_WD), .OPCODE_WD(OPCODE_WD)) U_ALU(.alu_out(alu_out),.zero_flag(alu_zero_flag),.alu_in1(Y_out),.alu_in2(bus1),.opcode(opcode));
endmodule//: processing_unit&#96;endif
感觉这代码写的还是挺好看的&#xff0c;甚至不需要做太多解释&#xff0c;具体实现可以参考1。
已经完成全部子模块代码了&#xff0c;那么就可以直接拼接定层了&#xff0c;先把参数文件贴一下&#xff1a;
parameter WORD_WD &#61; 8,
parameter MEM_SIZE &#61; 256,
parameter ADDR_WD &#61; $clog2(MEM_SIZE),
parameter OPCODE_NUM &#61; 9,
parameter OPCODE_WD &#61; $clog2(OPCODE_NUM),
parameter SRC_WD &#61; 2,
parameter DEST_WD &#61; 2,parameter SEL1_NUM &#61; 5,
parameter SEL2_NUM &#61; 3,
parameter SEL1_WD &#61; $clog2(SEL1_NUM),
parameter SEL2_WD &#61; $clog2(SEL2_NUM),parameter NOP &#61; &#39;b0000,
parameter ADD &#61; &#39;b0001,
parameter SUB &#61; &#39;b0010,
parameter AND &#61; &#39;b0011,
parameter NOT &#61; &#39;b0100,
parameter RD &#61; &#39;b0101,
parameter WR &#61; &#39;b0110,
parameter BR &#61; &#39;b0111,
parameter BRZ &#61; &#39;b0111,parameter STATE_NUM &#61; 12,
parameter STATE_WD &#61; $clog2(STATE_NUM),
parameter S_IDLE &#61; &#39;h0,
parameter S_FET1 &#61; &#39;h1,
parameter S_FET2 &#61; &#39;h2,
parameter S_DEC &#61; &#39;h3,
parameter S_EX1 &#61; &#39;h4,
parameter S_RD1 &#61; &#39;h5,
parameter S_RD2 &#61; &#39;h6,
parameter S_WR1 &#61; &#39;h7,
parameter S_WR2 &#61; &#39;h8,
parameter S_BR1 &#61; &#39;h9,
parameter S_BR2 &#61; &#39;ha,
parameter S_HALT &#61; &#39;hb,parameter SEL_R0 &#61; 0,
parameter SEL_R1 &#61; 1,
parameter SEL_R2 &#61; 2,
parameter SEL_R3 &#61; 3,parameter DISPLAY_EN &#61; 0
接下来就是定层代码&#xff1a;
module RISC_SPM #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(input clk, rst_n
);wire ctrl2proc_load_R0;wire ctrl2proc_load_R1;wire ctrl2proc_load_R2;wire ctrl2proc_load_R3;wire ctrl2proc_load_PC;wire ctrl2proc_load_IR;wire ctrl2proc_load_reg_Y;wire ctrl2proc_load_reg_Z;wire ctrl2proc_load_add_R;wire ctrl2proc_inc_PC;wire [SEL1_WD -1:0] ctrl2proc_mux1_sel_to_bus1;wire [SEL2_WD -1:0] ctrl2proc_mux2_sel_to_bus2;wire ctrl2mem_write;wire [WORD_WD -1:0] mem2proc_data;wire [WORD_WD -1:0] proc2ctrl_instruction;wire proc2ctrl_zero_flag;wire [ADDR_WD -1:0] proc2mem_addr;wire [WORD_WD -1:0] proc2mem_data;ctrl_unit U_CTRL(.load_R0(ctrl2proc_load_R0), .load_R1(ctrl2proc_load_R1), .load_R2(ctrl2proc_load_R2), .load_R3(ctrl2proc_load_R3),.load_PC(ctrl2proc_load_PC), .load_IR(ctrl2proc_load_IR),.load_reg_Y(ctrl2proc_load_reg_Y),.load_reg_Z(ctrl2proc_load_reg_Z),.load_add_R(ctrl2proc_load_add_R),.inc_PC(ctrl2proc_inc_PC), .mux1_sel_to_bus1(ctrl2proc_mux1_sel_to_bus1),.mux2_sel_to_bus2(ctrl2proc_mux2_sel_to_bus2),.write(ctrl2mem_write),.instruction(proc2ctrl_instruction),.zero_flag(proc2ctrl_zero_flag),.clk(clk),.rst_n(rst_n));processing_unit U_PROCESSING(.instruction(proc2ctrl_instruction),.zero_flag(proc2ctrl_zero_flag),.addr(proc2mem_addr),.bus1(proc2mem_data),.mem_word(mem2proc_data),.load_R0(ctrl2proc_load_R0), .load_R1(ctrl2proc_load_R1), .load_R2(ctrl2proc_load_R2), .load_R3(ctrl2proc_load_R3),.load_PC(ctrl2proc_load_PC), .load_IR(ctrl2proc_load_IR),.load_reg_Y(ctrl2proc_load_reg_Y),.load_reg_Z(ctrl2proc_load_reg_Z),.load_add_R(ctrl2proc_load_add_R),.inc_PC(ctrl2proc_inc_PC),.mux1_sel_to_bus1(ctrl2proc_mux1_sel_to_bus1),.mux2_sel_to_bus2(ctrl2proc_mux2_sel_to_bus2),.clk(clk), .rst_n(rst_n));mem_unit #(.DISPLAY_EN(1)) U_MEM(.data_out(mem2proc_data),.data_in(proc2mem_data),.addr_in(proc2mem_addr),.write_en(ctrl2mem_write),.clk(clk),.rst_n(rst_n));endmodule
可以很清楚的看到&#xff0c;定层只有两个接口信号&#xff1a;clk和rst_n&#xff0c;也就是说软件与处理器交互&#xff0c;全部都是通过mem中存储指令&#xff0c;再从mem中读取结果来完成的。