From ff1c1630b2f864a85952bcb39c86438cc2bcc560 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Tue, 12 Nov 2024 00:20:29 -0800 Subject: [PATCH 01/18] data path: add initial wires and buffers --- data_path.v | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/data_path.v b/data_path.v index 1a03fd3..0ee8553 100644 --- a/data_path.v +++ b/data_path.v @@ -29,6 +29,74 @@ input [`CTRL_WIDTH_INDEX_LIMIT:0] CTRL; input CLK, RST; input [`DATA_INDEX_LIMIT:0] DATA_IN; -// TBD +wire pc_load, pc_sel_1, pc_sel_2, pc_sel_3, + ir_load, reg_r, reg_w, + r1_sel_1, wa_sel_1, wa_sel_2, wa_sel_3, + + sp_load, op1_sel_1, + op2_sel_1, op2_sel_2, op2_sel_3, op2_sel_4, + + wd_sel_1, wd_sel_2, wd_sel_3, + ma_sel_1, ma_sel_2, + md_sel_1; + +wire alu_oprn [5:0]; + +buf (pc_load, CTRL[0]); +buf (pc_sel_1, CTRL[1]); +buf (pc_sel_2, CTRL[2]); +buf (pc_sel_3, CTRL[3]); + +buf (ir_load, CTRL[4]); +buf (reg_r, CTRL[5]); +buf (reg_w, CTRL[6]); + +buf (r1_sel_1, CTRL[7]); +buf (wa_sel_1, CTRL[8]); +buf (wa_sel_2, CTRL[9]); +buf (wa_sel_3, CTRL[10]); + +buf (sp_load, CTRL[11]); +buf (op1_sel_1, CTRL[12]); + +buf (op2_sel_1, CTRL[13]); +buf (op2_sel_2, CTRL[14]); +buf (op2_sel_3, CTRL[15]); +buf (op2_sel_4, CTRL[16]); + +buf (wd_sel_1, CTRL[17]); +buf (wd_sel_2, CTRL[18]); +buf (wd_sel_3, CTRL[19]); + +buf (ma_sel_1, CTRL[20]); +buf (ma_sel_2, CTRL[21]); + +buf (md_sel_1, CTRL[22]); + +buf alu_oprn_buf [5:0] (alu_oprn, CTRL[28:23]); + +// Parse the instruction data +wire [5:0] opcode; +wire [4:0] rs; +wire [4:0] rt; +wire [4:0] rd; +wire [4:0] shamt; +wire [5:0] funct; +wire [15:0] imm; +wire [25:0] addr; + +// common for all +buf opcode_buf [5:0] (opcode, DATA_IN[31:26]); +// common for R-type, I-type +buf rs_buf [4:0] (rs, DATA_IN[25:21]); +buf rt_buf [4:0] (rt, DATA_IN[20:16]); +// for R-type +buf rd_buf [4:0] (rd, DATA_IN[15:11]); +buf shamt_buf [4:0] (shamt, DATA_IN[10:6]); +buf funct_buf [5:0] (funct, DATA_IN[5:0]); +// for I-type +buf imm_buf [15:0] (imm, DATA_IN[15:0]); +// for J-type +buf addr_buf [25:0] (addr, DATA_IN[25:0]); endmodule -- 2.47.2 From a2d547df455b1b3aeffbd3bab151ad3d877fd208 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Tue, 12 Nov 2024 01:49:30 -0800 Subject: [PATCH 02/18] data path: initial gate level implementation --- data_path.v | 89 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 8 deletions(-) diff --git a/data_path.v b/data_path.v index 0ee8553..f9c89dd 100644 --- a/data_path.v +++ b/data_path.v @@ -75,6 +75,16 @@ buf (md_sel_1, CTRL[22]); buf alu_oprn_buf [5:0] (alu_oprn, CTRL[28:23]); +// variables +wire [31:0] ir; // Instruction Register +wire [31:0] r1, r2; // Register File +wire [31:0] pc, pc_inc; // Program Counter +wire [31:0] sp; // Stack Pointer +wire [31:0] alu_out; // ALU output + +// TODO: Why? +buf ir_buf [31:0] (INSTRUCTION, ir); + // Parse the instruction data wire [5:0] opcode; wire [4:0] rs; @@ -86,17 +96,80 @@ wire [15:0] imm; wire [25:0] addr; // common for all -buf opcode_buf [5:0] (opcode, DATA_IN[31:26]); +buf opcode_buf [5:0] (opcode, ir[31:26]); // common for R-type, I-type -buf rs_buf [4:0] (rs, DATA_IN[25:21]); -buf rt_buf [4:0] (rt, DATA_IN[20:16]); +buf rs_buf [4:0] (rs, ir[25:21]); +buf rt_buf [4:0] (rt, ir[20:16]); // for R-type -buf rd_buf [4:0] (rd, DATA_IN[15:11]); -buf shamt_buf [4:0] (shamt, DATA_IN[10:6]); -buf funct_buf [5:0] (funct, DATA_IN[5:0]); +buf rd_buf [4:0] (rd, ir[15:11]); +buf shamt_buf [4:0] (shamt, ir[10:6]); +buf funct_buf [5:0] (funct, ir[5:0]); // for I-type -buf imm_buf [15:0] (imm, DATA_IN[15:0]); +buf imm_buf [15:0] (imm, ir[15:0]); // for J-type -buf addr_buf [25:0] (addr, DATA_IN[25:0]); +buf addr_buf [25:0] (addr, ir[25:0]); + + +// Instruction Register input +// Instruction Register +REG32 ir_inst(.Q(ir), .D(DATA_IN), .LOAD(ir_load), .CLK(CLK), .RESET(RST)); + +// Register File Input +wire [31:0] r1_sel, wa_sel, wd_sel; +wire [31:0] wa_sel_p1, wa_sel_p2, wd_sel_p1, wd_sel_p2; +wire [31:0] imm_zx_lsb; +buf imm_zx_lsb_buf [31:0] (imm_zx_lsb, {imm, 16'b0}); +MUX32_2x1 mux_r1_sel(r1_sel, rs, 32'b0, r1_sel_1); +MUX32_2x1 mux_wa_sel_p1(wa_sel_p1, rd, rt, wa_sel_1); +// TODO: Why 31? +MUX32_2x1 mux_wa_sel_p2(wa_sel_p2, 32'b0, 31, wa_sel_2); +MUX32_2x1 mux_wa_sel(wa_sel, wa_sel_p2, wa_sel_p1, wa_sel_3); +MUX32_2x1 mux_wd_sel_p1(wd_sel_p1, alu_out,DATA_IN, wd_sel_1); +MUX32_2x1 mux_wd_sel_p2(wd_sel_p2, wd_sel_p1, imm_zx_lsb, wd_sel_2); +MUX32_2x1 mux_wd_sel(wd_sel, pc_inc, wd_sel_p2, wd_sel_3); +// Register File +REGISTER_FILE_32x32 rf_inst(.DATA_R1(r1), .DATA_R2(r2), .ADDR_R1(r1_sel), .ADDR_R2(rt), + .DATA_W(wd_sel), .ADDR_W(wa_sel), .READ(reg_r), .WRITE(reg_w), .CLK(CLK), .RST(RST)); + +// ALU Input +wire [31:0] op1_sel, op2_sel; +wire [31:0] op2_sel_p1, op2_sel_p2, op2_sel_p3; +wire [31:0] shamt_zx, imm_sx, imm_zx; +buf shamt_zx_buf [31:0] (shamt_zx, {27'b0, shamt}); +buf imm_sx_buf [31:0] (imm_sx, {{16{imm[15]}}, imm}); +buf imm_zx_buf [31:0] (imm_zx, {16'b0, imm}); +MUX32_2x1 mux_op1_sel(op1_sel, r1, sp, op1_sel_1); +MUX32_2x1 mux_op2_sel_p1(op2_sel_p1, 31'b1, shamt_zx, op2_sel_1); +MUX32_2x1 mux_op2_sel_p2(op2_sel_p2, imm_zx, imm_sx, op2_sel_2); +MUX32_2x1 mux_op2_sel_p3(op2_sel_p3, op2_sel_p2, op2_sel_p1, op2_sel_3); +MUX32_2x1 mux_op2_sel(op2_sel, op2_sel_p3, r2, op2_sel_4); +// ALU +ALU alu_inst(.Y(alu_out), .ZERO(ZERO), .OP1(op1_sel), .OP2(op2_sel), .OPRN(alu_oprn)); + +// Progam Counter Input +wire [31:0] pc_sel; +wire [31:0] pc_offset, pc_jump, pc_sel_p1, pc_sel_p2; +RC_ADD_SUB_32 pc_inc_inst(.Y(pc_inc), .A(pc), .B(32'b1), .SnA(1'b0)); +MUX32_2x1 mux_pc_sel_p1(pc_sel_p1, r1, pc_inc, pc_sel_1); +RC_ADD_SUB_32 pc_sel_2_inst(.Y(pc_offset), .A(pc), .B(imm_sx), .SnA(1'b0)); +MUX32_2x1 mux_pc_sel_p2(pc_sel_p2, pc_sel_p1, pc_offset, pc_sel_2); +buf pc_jump_buf [31:0] (pc_jump, {6'b0, addr}); +MUX32_2x1 mux_pc_sel(pc_sel, pc_jump, pc_sel_p2, pc_sel_3); +// Program Counter +defparam pc_inst.PATTERN = `INST_START_ADDR; +REG32_PP pc_inst(.Q(pc), .D(pc_sel), .LOAD(pc_load), .CLK(CLK), .RESET(RST)); + +// Stack Pointer +defparam sp_inst.PATTERN = `INIT_STACK_POINTER; +REG32_PP sp_inst(.Q(sp), .D(alu_out), .LOAD(sp_load), .CLK(CLK), .RESET(RST)); + +// Data out +MUX32_2x1 mux_data_out(DATA_OUT, r2, r1, md_sel_1); + +// Address out +wire [31:0] ma_sel_p1; +MUX32_2x1 mux_ma_sel_p1(ma_sel_p1, alu_out, sp, ma_sel_1); +// TODO: Check address calculation since it's 26 bit +MUX32_2x1 mux_ma_sel(ADDR, ma_sel_p1, pc, ma_sel_2); endmodule -- 2.47.2 From d10a3d61308a5c8d1aec0f8a018c049f9d48fa71 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Tue, 12 Nov 2024 01:49:30 -0800 Subject: [PATCH 03/18] data path: fix port connection warnings --- data_path.v | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/data_path.v b/data_path.v index f9c89dd..5e6ac98 100644 --- a/data_path.v +++ b/data_path.v @@ -40,7 +40,7 @@ wire pc_load, pc_sel_1, pc_sel_2, pc_sel_3, ma_sel_1, ma_sel_2, md_sel_1; -wire alu_oprn [5:0]; +wire [5:0] alu_oprn; buf (pc_load, CTRL[0]); buf (pc_sel_1, CTRL[1]); @@ -119,8 +119,8 @@ wire [31:0] r1_sel, wa_sel, wd_sel; wire [31:0] wa_sel_p1, wa_sel_p2, wd_sel_p1, wd_sel_p2; wire [31:0] imm_zx_lsb; buf imm_zx_lsb_buf [31:0] (imm_zx_lsb, {imm, 16'b0}); -MUX32_2x1 mux_r1_sel(r1_sel, rs, 32'b0, r1_sel_1); -MUX32_2x1 mux_wa_sel_p1(wa_sel_p1, rd, rt, wa_sel_1); +MUX32_2x1 mux_r1_sel(r1_sel, {27'b0,rs}, 32'b0, r1_sel_1); +MUX32_2x1 mux_wa_sel_p1(wa_sel_p1, {27'b0,rd}, {27'b0,rt}, wa_sel_1); // TODO: Why 31? MUX32_2x1 mux_wa_sel_p2(wa_sel_p2, 32'b0, 31, wa_sel_2); MUX32_2x1 mux_wa_sel(wa_sel, wa_sel_p2, wa_sel_p1, wa_sel_3); @@ -128,8 +128,8 @@ MUX32_2x1 mux_wd_sel_p1(wd_sel_p1, alu_out,DATA_IN, wd_sel_1); MUX32_2x1 mux_wd_sel_p2(wd_sel_p2, wd_sel_p1, imm_zx_lsb, wd_sel_2); MUX32_2x1 mux_wd_sel(wd_sel, pc_inc, wd_sel_p2, wd_sel_3); // Register File -REGISTER_FILE_32x32 rf_inst(.DATA_R1(r1), .DATA_R2(r2), .ADDR_R1(r1_sel), .ADDR_R2(rt), - .DATA_W(wd_sel), .ADDR_W(wa_sel), .READ(reg_r), .WRITE(reg_w), .CLK(CLK), .RST(RST)); +REGISTER_FILE_32x32 rf_inst(.DATA_R1(r1), .DATA_R2(r2), .ADDR_R1(r1_sel[4:0]), .ADDR_R2(rt), + .DATA_W(wd_sel), .ADDR_W(wa_sel[4:0]), .READ(reg_r), .WRITE(reg_w), .CLK(CLK), .RST(RST)); // ALU Input wire [31:0] op1_sel, op2_sel; @@ -139,19 +139,19 @@ buf shamt_zx_buf [31:0] (shamt_zx, {27'b0, shamt}); buf imm_sx_buf [31:0] (imm_sx, {{16{imm[15]}}, imm}); buf imm_zx_buf [31:0] (imm_zx, {16'b0, imm}); MUX32_2x1 mux_op1_sel(op1_sel, r1, sp, op1_sel_1); -MUX32_2x1 mux_op2_sel_p1(op2_sel_p1, 31'b1, shamt_zx, op2_sel_1); +MUX32_2x1 mux_op2_sel_p1(op2_sel_p1, 32'b1, shamt_zx, op2_sel_1); MUX32_2x1 mux_op2_sel_p2(op2_sel_p2, imm_zx, imm_sx, op2_sel_2); MUX32_2x1 mux_op2_sel_p3(op2_sel_p3, op2_sel_p2, op2_sel_p1, op2_sel_3); MUX32_2x1 mux_op2_sel(op2_sel, op2_sel_p3, r2, op2_sel_4); // ALU -ALU alu_inst(.Y(alu_out), .ZERO(ZERO), .OP1(op1_sel), .OP2(op2_sel), .OPRN(alu_oprn)); +ALU alu_inst(.OUT(alu_out), .ZERO(ZERO), .OP1(op1_sel), .OP2(op2_sel), .OPRN(alu_oprn)); // Progam Counter Input wire [31:0] pc_sel; wire [31:0] pc_offset, pc_jump, pc_sel_p1, pc_sel_p2; -RC_ADD_SUB_32 pc_inc_inst(.Y(pc_inc), .A(pc), .B(32'b1), .SnA(1'b0)); +RC_ADD_SUB_32 pc_inc_inst(.Y(pc_inc), .CO(), .A(pc), .B(32'b1), .SnA(1'b0)); MUX32_2x1 mux_pc_sel_p1(pc_sel_p1, r1, pc_inc, pc_sel_1); -RC_ADD_SUB_32 pc_sel_2_inst(.Y(pc_offset), .A(pc), .B(imm_sx), .SnA(1'b0)); +RC_ADD_SUB_32 pc_sel_2_inst(.Y(pc_offset), .CO(), .A(pc), .B(imm_sx), .SnA(1'b0)); MUX32_2x1 mux_pc_sel_p2(pc_sel_p2, pc_sel_p1, pc_offset, pc_sel_2); buf pc_jump_buf [31:0] (pc_jump, {6'b0, addr}); MUX32_2x1 mux_pc_sel(pc_sel, pc_jump, pc_sel_p2, pc_sel_3); @@ -170,6 +170,8 @@ MUX32_2x1 mux_data_out(DATA_OUT, r2, r1, md_sel_1); wire [31:0] ma_sel_p1; MUX32_2x1 mux_ma_sel_p1(ma_sel_p1, alu_out, sp, ma_sel_1); // TODO: Check address calculation since it's 26 bit -MUX32_2x1 mux_ma_sel(ADDR, ma_sel_p1, pc, ma_sel_2); +(* keep="soft" *) +wire [5:0] _addr_ignored; +MUX32_2x1 mux_ma_sel({_addr_ignored,ADDR}, ma_sel_p1, pc, ma_sel_2); endmodule -- 2.47.2 From 88b635122f05b495a903c916e1de2800da5b14fb Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Tue, 12 Nov 2024 18:02:06 -0800 Subject: [PATCH 04/18] (WIP) control unit: initial implementation of things --- control_unit.v | 338 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 332 insertions(+), 6 deletions(-) diff --git a/control_unit.v b/control_unit.v index b2bda1c..c7ed4fe 100644 --- a/control_unit.v +++ b/control_unit.v @@ -18,7 +18,7 @@ // 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation //------------------------------------------------------------------------------------------ `include "prj_definition.v" -module CONTROL_UNIT(CTRL, READ, WRITE, ZERO, INSTRUCTION, CLK, RST); +module CONTROL_UNIT(CTRL, READ, WRITE, ZERO, INSTRUCTION, CLK, RST); // Output signals output [`CTRL_WIDTH_INDEX_LIMIT:0] CTRL; output READ, WRITE; @@ -26,8 +26,315 @@ output READ, WRITE; // input signals input ZERO, CLK, RST; input [`DATA_INDEX_LIMIT:0] INSTRUCTION; - + +task print_instruction; +input [`DATA_INDEX_LIMIT:0] inst; +reg [5:0] opcode2; +reg [4:0] rs2; +reg [4:0] rt2; +reg [4:0] rd2; +reg [4:0] shamt2; +reg [5:0] funct2; +reg [15:0] immediate2; +reg [25:0] address2; +begin +// parse the instruction +// R-type +{opcode2, rs2, rt2, rd2, shamt2, funct2} = inst; +// I-type +{opcode2, rs2, rt2, immediate2 } = inst; +// J-type +{opcode2, address2} = inst; + +$write("@ %6dns -> [0X%08h] ", $time, inst); + +case(opcode2) +// R-Type +6'h00 : begin + case(funct2) + 6'h20: $write("add r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h01: $write("sll r[%02d], r[%02d], %2d;", rd2, rs2, shamt2); + 6'h02: $write("srl r[%02d], 0X%02h, r[%02d];", rd2, rs2, shamt2); + 6'h08: $write("jr r[%02d];", rs2); + default: begin $write(""); + end + endcase + end +// I-type +6'h08 : $write("addi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); +6'h1d : $write("muli r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); +6'h0c : $write("andi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); +6'h0d : $write("ori r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); +6'h0f : $write("lui r[%02d], 0X%04h;", rt2, immediate2); +6'h0a : $write("slti r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); +6'h04 : $write("beq r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); +6'h05 : $write("bne r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); +6'h23 : $write("lw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); +6'h2b : $write("sw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); +// J-Type +6'h02 : $write("jmp 0X%07h;", address2); +6'h03 : $write("jal 0X%07h;", address2); +6'h1b : $write("push;"); +6'h1c : $write("pop;"); +default: $write(""); +endcase + +$write("\n"); +end +endtask +//------------------------------------- END ---------------------------------------// + + +reg read, write; +assign READ = read; +assign WRITE = write; + +// Control signals, same as in data_path.v +reg pc_load, pc_sel_1, pc_sel_2, pc_sel_3, + ir_load, reg_r, reg_w, + r1_sel_1, wa_sel_1, wa_sel_2, wa_sel_3, + + sp_load, op1_sel_1, + op2_sel_1, op2_sel_2, op2_sel_3, op2_sel_4, + + wd_sel_1, wd_sel_2, wd_sel_3, + ma_sel_1, ma_sel_2, + md_sel_1; + +reg [5:0] alu_oprn; + +buf (CTRL[0], pc_load); +buf (CTRL[1], pc_sel_1); +buf (CTRL[2], pc_sel_2); +buf (CTRL[3], pc_sel_3); + +buf (CTRL[4], ir_load); +buf (CTRL[5], reg_r); +buf (CTRL[6], reg_w); + +buf (CTRL[7], r1_sel_1); +buf (CTRL[8], wa_sel_1); +buf (CTRL[9], wa_sel_2); +buf (CTRL[10], wa_sel_3); + +buf (CTRL[11], sp_load); +buf (CTRL[12], op1_sel_1); + +buf (CTRL[13], op2_sel_1); +buf (CTRL[14], op2_sel_2); +buf (CTRL[15], op2_sel_3); +buf (CTRL[16], op2_sel_4); + +buf (CTRL[17], wd_sel_1); +buf (CTRL[18], wd_sel_2); +buf (CTRL[19], wd_sel_3); + +buf (CTRL[20], ma_sel_1); +buf (CTRL[21], ma_sel_2); + +buf (CTRL[22], md_sel_1); + +buf alu_oprn_buf [5:0] (CTRL[28:23], alu_oprn); + +// Parse the instruction data, same as in data_path.v +wire [5:0] opcode; +wire [4:0] rs; +wire [4:0] rt; +wire [4:0] rd; +wire [4:0] shamt; +wire [5:0] funct; +wire [15:0] imm; +wire [25:0] addr; + +// common for all +buf opcode_buf [5:0] (opcode, INSTRUCTION[31:26]); +// common for R-type, I-type +buf rs_buf [4:0] (rs, INSTRUCTION[25:21]); +buf rt_buf [4:0] (rt, INSTRUCTION[20:16]); +// for R-type +buf rd_buf [4:0] (rd, INSTRUCTION[15:11]); +buf shamt_buf [4:0] (shamt, INSTRUCTION[10:6]); +buf funct_buf [5:0] (funct, INSTRUCTION[5:0]); +// for I-type +buf imm_buf [15:0] (imm, INSTRUCTION[15:0]); +// for J-type +buf addr_buf [25:0] (addr, INSTRUCTION[25:0]); + +// State machine +wire [2:0] state; +PROC_SM proc_sm(state, CLK, RST); + // TBD - take action on each +ve edge of clock +always @ (state) begin + // Print current state + $write("@ %6dns -> ", $time); + $write("STATE ", state, ": "); + case (state) + `PROC_FETCH: $write("FETCH"); + `PROC_DECODE: $write("DECODE"); + `PROC_EXE: $write("EXECUTE"); + `PROC_MEM: $write("MEMORY"); + `PROC_WB: $write("WRITE BACK"); + default: $write("INVALID"); + endcase + + case (state) + // fetch - next instruction from memory at PC + `PROC_FETCH: begin + // loaded in previous state, set to 0 + pc_load = 1'b0; + reg_r = 1'b0; + reg_w = 1'b0; + // load now + ir_load = 1'b1; + read = 1'b1; + write = 1'b0; + // selections + // ma_sel_2 - load data from mem[PC] + ma_sel_2 = 1'b1; + end + // decode - parse instruction and read values from register file + `PROC_DECODE: begin + // loaded in previous state, set to 0 + ir_load = 1'b0; + sp_load = 1'b0; + read = 1'b0; + // load now + reg_r = 1'b1; + reg_w = 1'b0; + // selections + // r1_sel_1: push - store value of r0 at stack pointer + r1_sel_1 = opcode != 6'h1b ? 1'b0 : 1'b1; + // wa_sel_1: R-type - write to rd, I-type - write to rt + wa_sel_1 = opcode == 6'h00 ? 1'b0 : 1'b1; + // wa_sel_2: jal - write to r31, pop - write to r0 + wa_sel_2 = opcode == 6'h03 ? 1'b1 : 1'b0; + // wa_sel_3: push or pop - wa_sel_2, else wa_sel_1 + wa_sel_3 = opcode == 6'h03 || opcode == 6'h1c ? 1'b0 : 1'b1; + // jr - jump to address in register + pc_sel_1 = opcode == 6'h00 && funct == 6'h08 ? 1'b0 : 1'b1; + // beq, bne - branch if equal or not equal + // TODO: this should only be selected if the condition is met + // pc_sel_2 = opcode == 6'h04 || opcode == 6'h05 ? 1'b1 : 1'b0; + // jmp, jal - jump to address + pc_sel_3 = opcode == 6'h02 || opcode == 6'h03 ? 1'b0 : 1'b1; + + // alu_oprn - operation to be performed by ALU + // R-type + if (opcode == 6'h00) begin + case (funct) + 6'h20: alu_oprn = 6'h01; // add + 6'h22: alu_oprn = 6'h02; // sub + 6'h2c: alu_oprn = 6'h03; // mul + 6'h02: alu_oprn = 6'h04; // srl + 6'h01: alu_oprn = 6'h05; // sll + 6'h24: alu_oprn = 6'h06; // and + 6'h25: alu_oprn = 6'h07; // or + 6'h27: alu_oprn = 6'h08; // nor + 6'h2a: alu_oprn = 6'h09; // slt + default: alu_oprn = 6'hxx; + endcase + end + // I-type and J-type + else begin + case (opcode) + // I-type + 6'h08: alu_oprn = 6'h01; // addi + 6'h1d: alu_oprn = 6'h03; // muli + 6'h0c: alu_oprn = 6'h06; // andi + 6'h0d: alu_oprn = 6'h07; // ori + 6'h0a: alu_oprn = 6'h09; // slti + 6'h04: alu_oprn = 6'h02; // beq - sub + 6'h05: alu_oprn = 6'h02; // bne - sub + 6'h23: alu_oprn = 6'h01; // lw - add + 6'h2b: alu_oprn = 6'h01; // sw - add + // J-type + 6'h1b: alu_oprn = 6'h02; // push - sub + 6'h1c: alu_oprn = 6'h01; // pop - add + default: alu_oprn = 6'hxx; + endcase + end + // op1_sel_1 - select r1 or sp based on opcode + // push or pop - sp, else r1 + op1_sel_1 = opcode == 6'h1b || opcode == 6'h1c ? 1'b1 : 1'b0; + // op2_sel_1 - select 1 or shamt based on alu_oprn + // sll or srl - shamt, else 1 (for increments/decrements) + op2_sel_1 = alu_oprn == 6'h04 || alu_oprn == 6'h05 ? 1'b1 : 1'b0; + // op2_sel_2 - select imm_zx or imm_sx based on alu_oprn + // logical (and, or) - imm_zx, else imm_sx; ('nor' not availble in I-type) + op2_sel_2 = alu_oprn == 6'h06 || alu_oprn == 6'h07 ? 1'b0 : 1'b1; + // op2_sel_3 - select op2_sel_2 or op2_sel_1 based on alu_oprn + // R-type - op2_sel_1, I-type - op2_sel_2 + op2_sel_3 = opcode == 6'h00 ? 1'b1 : 1'b0; + // op2_sel_4 - select op2_sel_3 or r2 + // I-type or shift or inc/dec - op2_sel_3, else r2 + // i.e. r2 only if R-type and not shift + op2_sel_4 = opcode != 6'h00 || alu_oprn == 6'h04 || alu_oprn == 6'h05 ? 1'b0 : 1'b1; + end + // execute - perform operation based on instruction + `PROC_EXE: begin + // selections + // wd_sel_1 - alu_out or DATA_IN + wd_sel_1 = 1'b0; + // wd_sel_2 - wd_sel_1 or imm_zx_lsb + // lui - imm_zx_lsb, else wd_sel_1 + wd_sel_2 = opcode == 6'h0f ? 1'b1 : 1'b0; + // wd_sel_3 - pc_inc or wd_sel_2 + // jal - pc_inc, else wd_sel_2 + wd_sel_3 = opcode == 6'h03 ? 1'b0 : 1'b1; + // md_sel_1 - r1 for push, r2 for sw + md_sel_1 = opcode == 6'h1b ? 1'b1 : 1'b0; + end + `PROC_MEM: begin + // load now + // push or sw - write to memory + if (opcode == 6'h1b || opcode == 6'h2b) begin + read = 1'b0; + write = 1'b1; + end + else begin + read = 1'b1; + write = 1'b0; + end + end + `PROC_WB: begin + // loaded in previous state, set to 0 + read = 1'b0; + write = 1'b0; + // load now + pc_load = 1'b1; + // write to register file if + // R-type (except jr) or I-type (except beq, bne, sw) or pop or jal + reg_w = (opcode == 6'h00 && funct != 6'h08) // R-type (except jr) + || (opcode == 6'h08 || opcode == 6'h1d || opcode == 6'h0c || opcode == 6'h0d + || opcode == 6'h0f || opcode == 6'h0a || opcode == 6'h23) // I-type (except beq, bne, sw) + || (opcode == 6'h1c || opcode == 6'h03) // pop or jal + ? 1'b1 : 1'b0; + // selections + // ma_sel_2 - load data from mem[PC] + ma_sel_2 = 1'b1; + // pc_sel_2 - branch if equal or not equal + pc_sel_2 = (opcode == 6'h04 && ZERO) || (opcode == 6'h05 && ~ZERO) ? 1'b1 : 1'b0; + + end + default: begin + $write("@ %6dns -> ", $time); + $write("STATE ", state, ": "); + $write("INVALID"); + print_instruction(INSTRUCTION); + end + endcase + + // TBD - assign control signals based on instruction + print_instruction(INSTRUCTION); + // TBD - assign READ and WRITE signals based on instruction +end endmodule @@ -35,13 +342,13 @@ endmodule //------------------------------------------------------------------------------------------ // Module: PROC_SM // Output: STATE : State of the processor -// +// // Input: CLK : Clock signal // RST : Reset signal // // INOUT: MEM_DATA : Data to be read in from or write to the memory // -// Notes: - Processor continuously cycle witnin fetch, decode, execute, +// Notes: - Processor continuously cycle witnin fetch, decode, execute, // memory, write back state. State values are in the prj_definition.v // // Revision History: @@ -56,6 +363,25 @@ input CLK, RST; // list of outputs output [2:0] STATE; -// TBD - take action on each +ve edge of clock +reg [2:0] state_sel = 3'bxxx; -endmodule \ No newline at end of file +always @ (negedge RST) begin + // set to invalid value, so that it defaults to fetch + state_sel = 3'bxxx; +end + +// TBD - take action on each +ve edge of clock +always @ (posedge CLK) begin + case (state_sel) + `PROC_FETCH: state_sel = `PROC_DECODE; + `PROC_DECODE: state_sel = `PROC_EXE; + `PROC_EXE: state_sel = `PROC_MEM; + `PROC_MEM: state_sel = `PROC_WB; + `PROC_WB: state_sel = `PROC_FETCH; + default: state_sel = `PROC_FETCH; + endcase +end + +assign STATE = state_sel; + +endmodule -- 2.47.2 From 02781c283fdbbf2be7df0044283a965c23a6ab3f Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Tue, 12 Nov 2024 19:26:45 -0800 Subject: [PATCH 05/18] project: add da vinci test programs --- .gitignore | 4 ++ GOLDEN/CS147_FL15_HW01_02_mem_dump_golden.dat | 13 ++++++ .../CS147_SP15_HW01_02_mem_dump_01_golden.dat | 9 ++++ .../CS147_SP15_HW01_02_mem_dump_02_golden.dat | 9 ++++ GOLDEN/CS147_SP17_HW01_02_mem_dump_golden.dat | 14 ++++++ GOLDEN/RevFib_mem_dump.golden.dat | 19 ++++++++ GOLDEN/fibonacci_mem_dump.golden.dat | 19 ++++++++ OUTPUT/CS147_FL15_HW01_02_mem_dump.dat | 13 ++++++ OUTPUT/CS147_SP17_HW01_02_mem_dump.dat | 14 ++++++ OUTPUT/RevFib_mem_dump.dat | 19 ++++++++ OUTPUT/fibonacci_mem_dump.dat | 19 ++++++++ OUTPUT/full_adder.out | 11 +++++ OUTPUT/half_adder.out | 7 +++ OUTPUT/mult32_tb.out | 11 +++++ OUTPUT/mult32_u_tb.out | 8 ++++ OUTPUT/rc_add_sub_32.out | 8 ++++ OUTPUT/twoscomp32_tb.out | 5 +++ OUTPUT/twoscomp64_tb.out | 5 +++ TESTPROGRAM/CS147_FL15_HW01_02.dat | 45 +++++++++++++++++++ TESTPROGRAM/CS147_SP15_HW01_02.dat | 21 +++++++++ TESTPROGRAM/CS147_SP17_HW01_02.dat | 28 ++++++++++++ TESTPROGRAM/RevFib.dat | 16 +++++++ TESTPROGRAM/fibonacci.dat | 13 ++++++ TESTPROGRAM/mem_content_01.dat | 11 +++++ 24 files changed, 341 insertions(+) create mode 100644 GOLDEN/CS147_FL15_HW01_02_mem_dump_golden.dat create mode 100644 GOLDEN/CS147_SP15_HW01_02_mem_dump_01_golden.dat create mode 100644 GOLDEN/CS147_SP15_HW01_02_mem_dump_02_golden.dat create mode 100644 GOLDEN/CS147_SP17_HW01_02_mem_dump_golden.dat create mode 100644 GOLDEN/RevFib_mem_dump.golden.dat create mode 100644 GOLDEN/fibonacci_mem_dump.golden.dat create mode 100644 OUTPUT/CS147_FL15_HW01_02_mem_dump.dat create mode 100644 OUTPUT/CS147_SP17_HW01_02_mem_dump.dat create mode 100644 OUTPUT/RevFib_mem_dump.dat create mode 100644 OUTPUT/fibonacci_mem_dump.dat create mode 100644 OUTPUT/full_adder.out create mode 100644 OUTPUT/half_adder.out create mode 100644 OUTPUT/mult32_tb.out create mode 100644 OUTPUT/mult32_u_tb.out create mode 100644 OUTPUT/rc_add_sub_32.out create mode 100644 OUTPUT/twoscomp32_tb.out create mode 100644 OUTPUT/twoscomp64_tb.out create mode 100644 TESTPROGRAM/CS147_FL15_HW01_02.dat create mode 100644 TESTPROGRAM/CS147_SP15_HW01_02.dat create mode 100644 TESTPROGRAM/CS147_SP17_HW01_02.dat create mode 100644 TESTPROGRAM/RevFib.dat create mode 100644 TESTPROGRAM/fibonacci.dat create mode 100644 TESTPROGRAM/mem_content_01.dat diff --git a/.gitignore b/.gitignore index 92f4c49..231faec 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,7 @@ sc_dpiheader.h vsim.dbg # End of https://www.toptal.com/developers/gitignore/api/modelsim + +!TESTPROGRAM/*.dat +!GOLDEN/*.dat +!OUTPUT/*.dat diff --git a/GOLDEN/CS147_FL15_HW01_02_mem_dump_golden.dat b/GOLDEN/CS147_FL15_HW01_02_mem_dump_golden.dat new file mode 100644 index 0000000..57d284a --- /dev/null +++ b/GOLDEN/CS147_FL15_HW01_02_mem_dump_golden.dat @@ -0,0 +1,13 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000020 +00000020 +00000010 +00000010 +00000009 +00000008 +00000008 +00000005 +00000004 +00000002 diff --git a/GOLDEN/CS147_SP15_HW01_02_mem_dump_01_golden.dat b/GOLDEN/CS147_SP15_HW01_02_mem_dump_01_golden.dat new file mode 100644 index 0000000..3c8b717 --- /dev/null +++ b/GOLDEN/CS147_SP15_HW01_02_mem_dump_01_golden.dat @@ -0,0 +1,9 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000001 +00000004 +00000004 +00000010 +00000010 +00000000 diff --git a/GOLDEN/CS147_SP15_HW01_02_mem_dump_02_golden.dat b/GOLDEN/CS147_SP15_HW01_02_mem_dump_02_golden.dat new file mode 100644 index 0000000..254ddab --- /dev/null +++ b/GOLDEN/CS147_SP15_HW01_02_mem_dump_02_golden.dat @@ -0,0 +1,9 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000020 +00000008 +00000008 +00000002 +00000002 diff --git a/GOLDEN/CS147_SP17_HW01_02_mem_dump_golden.dat b/GOLDEN/CS147_SP17_HW01_02_mem_dump_golden.dat new file mode 100644 index 0000000..fe7d590 --- /dev/null +++ b/GOLDEN/CS147_SP17_HW01_02_mem_dump_golden.dat @@ -0,0 +1,14 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000015 +00000017 +00000019 +0000001b +0000001d +0000001f +00000021 +00000023 +00000025 +00000025 +00000000 diff --git a/GOLDEN/RevFib_mem_dump.golden.dat b/GOLDEN/RevFib_mem_dump.golden.dat new file mode 100644 index 0000000..19b3b06 --- /dev/null +++ b/GOLDEN/RevFib_mem_dump.golden.dat @@ -0,0 +1,19 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +ffffffc9 +00000022 +ffffffeb +0000000d +fffffff8 +00000005 +fffffffd +00000002 +ffffffff +00000001 +00000000 +00000001 +00000001 +00000002 +00000003 +00000005 diff --git a/GOLDEN/fibonacci_mem_dump.golden.dat b/GOLDEN/fibonacci_mem_dump.golden.dat new file mode 100644 index 0000000..2c44fe1 --- /dev/null +++ b/GOLDEN/fibonacci_mem_dump.golden.dat @@ -0,0 +1,19 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000001 +00000001 +00000002 +00000003 +00000005 +00000008 +0000000d +00000015 +00000022 +00000037 +00000059 +00000090 +000000e9 +00000179 +00000262 diff --git a/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat b/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat new file mode 100644 index 0000000..6b4ebd8 --- /dev/null +++ b/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat @@ -0,0 +1,13 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 diff --git a/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat b/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat new file mode 100644 index 0000000..6e829de --- /dev/null +++ b/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat @@ -0,0 +1,14 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +0000000a +0000000b +0000000c +0000000d +0000000e +0000000f +00000010 +00000011 +00000012 +00000013 +00000000 diff --git a/OUTPUT/RevFib_mem_dump.dat b/OUTPUT/RevFib_mem_dump.dat new file mode 100644 index 0000000..78993eb --- /dev/null +++ b/OUTPUT/RevFib_mem_dump.dat @@ -0,0 +1,19 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 diff --git a/OUTPUT/fibonacci_mem_dump.dat b/OUTPUT/fibonacci_mem_dump.dat new file mode 100644 index 0000000..78993eb --- /dev/null +++ b/OUTPUT/fibonacci_mem_dump.dat @@ -0,0 +1,19 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 diff --git a/OUTPUT/full_adder.out b/OUTPUT/full_adder.out new file mode 100644 index 0000000..6c019d4 --- /dev/null +++ b/OUTPUT/full_adder.out @@ -0,0 +1,11 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/FULL_ADDER_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000001 +00000001 +00000002 +00000001 +00000002 +00000002 +00000003 diff --git a/OUTPUT/half_adder.out b/OUTPUT/half_adder.out new file mode 100644 index 0000000..7649f00 --- /dev/null +++ b/OUTPUT/half_adder.out @@ -0,0 +1,7 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/HALF_ADDER_TB/results +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000001 +00000001 +00000002 diff --git a/OUTPUT/mult32_tb.out b/OUTPUT/mult32_tb.out new file mode 100644 index 0000000..510e496 --- /dev/null +++ b/OUTPUT/mult32_tb.out @@ -0,0 +1,11 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/MULT_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000000000c8 +000000000000002d +ffffffffffffff90 +ffffffffffffff42 +3100000000000000 +cf00000000000000 +cf00000000000000 +3100000000000000 diff --git a/OUTPUT/mult32_u_tb.out b/OUTPUT/mult32_u_tb.out new file mode 100644 index 0000000..20b79ab --- /dev/null +++ b/OUTPUT/mult32_u_tb.out @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/MULT_U_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000000000c8 +000000000000002d +0000000000000070 +00000000000000be +006975a0b62bf524 diff --git a/OUTPUT/rc_add_sub_32.out b/OUTPUT/rc_add_sub_32.out new file mode 100644 index 0000000..4a19897 --- /dev/null +++ b/OUTPUT/rc_add_sub_32.out @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/RC_ADD_SUB_32_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +0000001e +fffffff6 +00000003 +00000004 +00005555 diff --git a/OUTPUT/twoscomp32_tb.out b/OUTPUT/twoscomp32_tb.out new file mode 100644 index 0000000..5e28566 --- /dev/null +++ b/OUTPUT/twoscomp32_tb.out @@ -0,0 +1,5 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/TWOSCOMP32_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +fffffff6 +00000005 diff --git a/OUTPUT/twoscomp64_tb.out b/OUTPUT/twoscomp64_tb.out new file mode 100644 index 0000000..b344911 --- /dev/null +++ b/OUTPUT/twoscomp64_tb.out @@ -0,0 +1,5 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/TWOSCOMP64_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +fffffffffffffff6 +0000000000000005 diff --git a/TESTPROGRAM/CS147_FL15_HW01_02.dat b/TESTPROGRAM/CS147_FL15_HW01_02.dat new file mode 100644 index 0000000..613370c --- /dev/null +++ b/TESTPROGRAM/CS147_FL15_HW01_02.dat @@ -0,0 +1,45 @@ +// ------ Program Part ---- +@0001000 +2021000A // addi r1, r1, 0xA; +20421008 // addi r2, r2, 0x1008; +00401301 // sll r2, r2, 0xC; +00411820 // add r3, r2, r1; +3C848000 // lui r4, r4, 0x8000; +8C450000 // LOOP: lw r5, r2,0x0; +8C660000 // lw r6, r3, 0x0; +00A63822 // sub r7, r5, r6; +00E44024 // and r8, r7, r4; +15280003 // bne r8, r9, L1; +20C00000 // addi r0, r6, 0x0; +20630001 // addi r3, r3, 0x1; +0800100F // jmp L2; +20A00000 // L1: addi r0, r5, 0x0; +20420001 // addi r2, r2, 0x1; +6C000000 // L2: push +2021FFFF // addi r1, r1, 0xFFFF; +1521FFF3 // bne r1, r9, LOOP; + + +// ------ Data Part ---- +@01008000 +005 // 01008000 +008 // 01008001 +009 // 01008002 +010 // 01008003 +020 // 01008004 +029 // 01008005 +02D // 01008006 +02F // 01008007 +032 // 01008008 +037 // 01008009 +002 // 0100800A +004 // 0100800B +008 // 0100800C +010 // 0100800D +020 // 0100800E +040 // 0100800F +080 // 01008010 +100 // 01008011 +200 // 01008012 +400 // 01008013 + diff --git a/TESTPROGRAM/CS147_SP15_HW01_02.dat b/TESTPROGRAM/CS147_SP15_HW01_02.dat new file mode 100644 index 0000000..d30e339 --- /dev/null +++ b/TESTPROGRAM/CS147_SP15_HW01_02.dat @@ -0,0 +1,21 @@ +@0001000 +20000001 // addi r0, r0, 0x1; +20210002 // addi r1, r1, 0x2; +20420000 // addi r2, r2, 0x0; +3C630100 // lui r3, 0x100; +34638000 // ori r3, r3, 0x8000; +20840005 // addi r4, r4, 0x5; +00010020 // LOOP: add r0, r0, r1; +00010822 // sub r1, r0, r1; +00010022 // sub r0, r0, r1; +AC610000 // sw r1, r3, 0x0; +20630001 // addi r3, r3, 0x1; +6C000000 // push; +00000041 // sll r0, r0, 0x1; +00200841 // sll r1, r1, 0x1; +20420001 // addi r2, r2, 0x1; +1482FFF6 // bne r2, r4, LOOP; + + + + diff --git a/TESTPROGRAM/CS147_SP17_HW01_02.dat b/TESTPROGRAM/CS147_SP17_HW01_02.dat new file mode 100644 index 0000000..8374977 --- /dev/null +++ b/TESTPROGRAM/CS147_SP17_HW01_02.dat @@ -0,0 +1,28 @@ +// ------ Program Part ---- +@0001000 +20001008 // addi r0, r0, 0x1008 +00000301 // sll r0, r0, 0xC +20420009 // addi r2, r2, 0x9 +10410007 // LOOP: beq r1, r2, END +8C030000 // lw r3, r0, 0x0 +8C040001 // lw r4, r0, 0x1 +00642820 // add r5, r3, r4 +AC050000 // sw r5, r0, 0x0 +20000001 // addi r0, r0, 0x1 +20210001 // addi r1, r1, 0x1 +08001003 // j LOOP +AC050000 // END: sw r5, r0, 0x0 + +// ------ Data Part ---- +@01008000 +0A // 0100 8000 +0B // 0100 8001 +0C // 0100 8002 +0D // 0100 8003 +0E // 0100 8004 +0F // 0100 8005 +10 // 0100 8006 +11 // 0100 8007 +12 // 0100 8008 +13 // 0100 8008 + diff --git a/TESTPROGRAM/RevFib.dat b/TESTPROGRAM/RevFib.dat new file mode 100644 index 0000000..9d52b1e --- /dev/null +++ b/TESTPROGRAM/RevFib.dat @@ -0,0 +1,16 @@ +@0001000 +20210005 // addi r1, r1, 0x5 +20420003 // addi r2, r2, 0x3 +20200000 // addi r0, r1, 0x0 +6c000000 // push +20400000 // loop : addi r0, r2, 0x0 +6c000000 // push +20430000 // addi r3, r2, 0x0 +00221022 // sub r2, r1, r2 +20610000 // addi r1, r3, 0x0 +08001004 // jmp loop +00000000 // nop +00000000 // nop + + + diff --git a/TESTPROGRAM/fibonacci.dat b/TESTPROGRAM/fibonacci.dat new file mode 100644 index 0000000..36cbd46 --- /dev/null +++ b/TESTPROGRAM/fibonacci.dat @@ -0,0 +1,13 @@ +@0001000 +20420001 // addi r2, r2, 0x0001; +3C000100 // lui r0, 0x0100; +AC010000 // sw r1, r0, 0x0000; +20000001 // loop: addi r0, r0, 0x0001; +AC020000 // sw r2, r0, 0x0000; +20430000 // addi r3, r2, 0x0000; +00411020 // add r2, r2, r1; +20610000 // addi r1, r3, 0x0000; +08001003 // jmp loop; + + + diff --git a/TESTPROGRAM/mem_content_01.dat b/TESTPROGRAM/mem_content_01.dat new file mode 100644 index 0000000..c0460f4 --- /dev/null +++ b/TESTPROGRAM/mem_content_01.dat @@ -0,0 +1,11 @@ +@0001000 +00414020 00414021 00414022 00414023 // sample data +00414024 00414025 00414026 00414027 +00414028 00414029 0041402a 0041402b +0041402c 0041402d 0041402e 0041402f + +@002f00a +00514020 00514021 00514022 00514023 +00514024 00514025 00514026 00514027 +00514028 00514029 0051402a 0051402b +0051402c 0051402d 0051402e 0051402f \ No newline at end of file -- 2.47.2 From c8baf4262a50bcbaf55bee8aa4718b37c98f0599 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Sat, 16 Nov 2024 23:54:09 -0800 Subject: [PATCH 06/18] project: edit ctrl signal to match doc --- control_unit.v | 33 +++++++++++++++++---------------- data_path.v | 33 +++++++++++++++++---------------- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/control_unit.v b/control_unit.v index c7ed4fe..3e66826 100644 --- a/control_unit.v +++ b/control_unit.v @@ -115,32 +115,33 @@ buf (CTRL[2], pc_sel_2); buf (CTRL[3], pc_sel_3); buf (CTRL[4], ir_load); -buf (CTRL[5], reg_r); -buf (CTRL[6], reg_w); -buf (CTRL[7], r1_sel_1); -buf (CTRL[8], wa_sel_1); -buf (CTRL[9], wa_sel_2); -buf (CTRL[10], wa_sel_3); +buf (CTRL[5], r1_sel_1); +buf (CTRL[6], reg_r); +buf (CTRL[7], reg_w); -buf (CTRL[11], sp_load); -buf (CTRL[12], op1_sel_1); +buf (CTRL[8], sp_load); -buf (CTRL[13], op2_sel_1); -buf (CTRL[14], op2_sel_2); -buf (CTRL[15], op2_sel_3); -buf (CTRL[16], op2_sel_4); +buf (CTRL[9], op1_sel_1); +buf (CTRL[10], op2_sel_1); +buf (CTRL[11], op2_sel_2); +buf (CTRL[12], op2_sel_3); +buf (CTRL[13], op2_sel_4); -buf (CTRL[17], wd_sel_1); -buf (CTRL[18], wd_sel_2); -buf (CTRL[19], wd_sel_3); +buf alu_oprn_buf [5:0] (CTRL[19:14], alu_oprn); buf (CTRL[20], ma_sel_1); buf (CTRL[21], ma_sel_2); buf (CTRL[22], md_sel_1); -buf alu_oprn_buf [5:0] (CTRL[28:23], alu_oprn); +buf (CTRL[23], wd_sel_1); +buf (CTRL[24], wd_sel_2); +buf (CTRL[25], wd_sel_3); + +buf (CTRL[26], wa_sel_1); +buf (CTRL[27], wa_sel_2); +buf (CTRL[28], wa_sel_3); // Parse the instruction data, same as in data_path.v wire [5:0] opcode; diff --git a/data_path.v b/data_path.v index 5e6ac98..ba9b54b 100644 --- a/data_path.v +++ b/data_path.v @@ -48,32 +48,33 @@ buf (pc_sel_2, CTRL[2]); buf (pc_sel_3, CTRL[3]); buf (ir_load, CTRL[4]); -buf (reg_r, CTRL[5]); -buf (reg_w, CTRL[6]); -buf (r1_sel_1, CTRL[7]); -buf (wa_sel_1, CTRL[8]); -buf (wa_sel_2, CTRL[9]); -buf (wa_sel_3, CTRL[10]); +buf (r1_sel_1, CTRL[5]); +buf (reg_r, CTRL[6]); +buf (reg_w, CTRL[7]); -buf (sp_load, CTRL[11]); -buf (op1_sel_1, CTRL[12]); +buf (sp_load, CTRL[8]); -buf (op2_sel_1, CTRL[13]); -buf (op2_sel_2, CTRL[14]); -buf (op2_sel_3, CTRL[15]); -buf (op2_sel_4, CTRL[16]); +buf (op1_sel_1, CTRL[9]); +buf (op2_sel_1, CTRL[10]); +buf (op2_sel_2, CTRL[11]); +buf (op2_sel_3, CTRL[12]); +buf (op2_sel_4, CTRL[13]); -buf (wd_sel_1, CTRL[17]); -buf (wd_sel_2, CTRL[18]); -buf (wd_sel_3, CTRL[19]); +buf alu_oprn_buf [5:0] (alu_oprn, CTRL[19:14]); buf (ma_sel_1, CTRL[20]); buf (ma_sel_2, CTRL[21]); buf (md_sel_1, CTRL[22]); -buf alu_oprn_buf [5:0] (alu_oprn, CTRL[28:23]); +buf (wd_sel_1, CTRL[23]); +buf (wd_sel_2, CTRL[24]); +buf (wd_sel_3, CTRL[25]); + +buf (wa_sel_1, CTRL[26]); +buf (wa_sel_2, CTRL[27]); +buf (wa_sel_3, CTRL[28]); // variables wire [31:0] ir; // Instruction Register -- 2.47.2 From 8810726d656d629d5615df3abe82551ddb8ddd6d Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Sun, 17 Nov 2024 00:42:38 -0800 Subject: [PATCH 07/18] project: minor refactors --- OUTPUT/CS147_FL15_HW01_02_mem_dump.dat | 13 --- OUTPUT/CS147_SP17_HW01_02_mem_dump.dat | 14 --- OUTPUT/RevFib_mem_dump.dat | 19 ----- OUTPUT/fibonacci_mem_dump.dat | 19 ----- control_unit.v | 114 +++++++++++++++---------- 5 files changed, 71 insertions(+), 108 deletions(-) delete mode 100644 OUTPUT/CS147_FL15_HW01_02_mem_dump.dat delete mode 100644 OUTPUT/CS147_SP17_HW01_02_mem_dump.dat delete mode 100644 OUTPUT/RevFib_mem_dump.dat delete mode 100644 OUTPUT/fibonacci_mem_dump.dat diff --git a/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat b/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat deleted file mode 100644 index 6b4ebd8..0000000 --- a/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat +++ /dev/null @@ -1,13 +0,0 @@ -// memory data file (do not edit the following line - required for mem load use) -// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m -// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 diff --git a/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat b/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat deleted file mode 100644 index 6e829de..0000000 --- a/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat +++ /dev/null @@ -1,14 +0,0 @@ -// memory data file (do not edit the following line - required for mem load use) -// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m -// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress -0000000a -0000000b -0000000c -0000000d -0000000e -0000000f -00000010 -00000011 -00000012 -00000013 -00000000 diff --git a/OUTPUT/RevFib_mem_dump.dat b/OUTPUT/RevFib_mem_dump.dat deleted file mode 100644 index 78993eb..0000000 --- a/OUTPUT/RevFib_mem_dump.dat +++ /dev/null @@ -1,19 +0,0 @@ -// memory data file (do not edit the following line - required for mem load use) -// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m -// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 diff --git a/OUTPUT/fibonacci_mem_dump.dat b/OUTPUT/fibonacci_mem_dump.dat deleted file mode 100644 index 78993eb..0000000 --- a/OUTPUT/fibonacci_mem_dump.dat +++ /dev/null @@ -1,19 +0,0 @@ -// memory data file (do not edit the following line - required for mem load use) -// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m -// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 diff --git a/control_unit.v b/control_unit.v index 3e66826..e9321b4 100644 --- a/control_unit.v +++ b/control_unit.v @@ -18,6 +18,40 @@ // 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation //------------------------------------------------------------------------------------------ `include "prj_definition.v" + +`define ALU_ADD 6'h01 +`define ALU_SUB 6'h02 +`define ALU_MUL 6'h03 +`define ALU_SRL 6'h04 +`define ALU_SLL 6'h05 +`define ALU_AND 6'h06 +`define ALU_OR 6'h07 +`define ALU_NOR 6'h08 +`define ALU_SLT 6'h09 + +`define OP_RTYPE 6'h00 +`define FN_ADD 6'h20 +`define FN_SUB 6'h22 +`define FN_MUL 6'h2c +`define FN_AND 6'h24 +`define FN_OR 6'h25 +`define FN_NOR 6'h27 +`define FN_SLT 6'h2a +`define FN_SLL 6'h01 +`define FN_SRL 6'h02 +`define FN_JR 6'h08 + +`define OP_ADDI 6'h08 +`define OP_MULI 6'h1d +`define OP_ANDI 6'h0c +`define OP_ORI 6'h0d +`define OP_LUI 6'h0f +`define OP_SLTI 6'h0a +`define OP_BEQ 6'h04 +`define OP_BNE 6'h05 +`define OP_LW 6'h23 +`define OP_SW 6'h2b + module CONTROL_UNIT(CTRL, READ, WRITE, ZERO, INSTRUCTION, CLK, RST); // Output signals output [`CTRL_WIDTH_INDEX_LIMIT:0] CTRL; @@ -143,29 +177,15 @@ buf (CTRL[26], wa_sel_1); buf (CTRL[27], wa_sel_2); buf (CTRL[28], wa_sel_3); -// Parse the instruction data, same as in data_path.v -wire [5:0] opcode; -wire [4:0] rs; -wire [4:0] rt; -wire [4:0] rd; -wire [4:0] shamt; -wire [5:0] funct; -wire [15:0] imm; -wire [25:0] addr; - -// common for all -buf opcode_buf [5:0] (opcode, INSTRUCTION[31:26]); -// common for R-type, I-type -buf rs_buf [4:0] (rs, INSTRUCTION[25:21]); -buf rt_buf [4:0] (rt, INSTRUCTION[20:16]); -// for R-type -buf rd_buf [4:0] (rd, INSTRUCTION[15:11]); -buf shamt_buf [4:0] (shamt, INSTRUCTION[10:6]); -buf funct_buf [5:0] (funct, INSTRUCTION[5:0]); -// for I-type -buf imm_buf [15:0] (imm, INSTRUCTION[15:0]); -// for J-type -buf addr_buf [25:0] (addr, INSTRUCTION[25:0]); +// Parse the instruction data +reg [5:0] opcode; +reg [4:0] rs; +reg [4:0] rt; +reg [4:0] rd; +reg [4:0] shamt; +reg [5:0] funct; +reg [15:0] imm; +reg [25:0] addr; // State machine wire [2:0] state; @@ -173,6 +193,13 @@ PROC_SM proc_sm(state, CLK, RST); // TBD - take action on each +ve edge of clock always @ (state) begin + // R-type + {opcode, rs, rt, rd, shamt, funct} = INSTRUCTION; + // I-type + {opcode, rs, rt, imm} = INSTRUCTION; + // J-type + {opcode, addr} = INSTRUCTION; + // Print current state $write("@ %6dns -> ", $time); $write("STATE ", state, ": "); @@ -184,6 +211,7 @@ always @ (state) begin `PROC_WB: $write("WRITE BACK"); default: $write("INVALID"); endcase + $write("\n"); case (state) // fetch - next instruction from memory at PC @@ -230,15 +258,15 @@ always @ (state) begin // R-type if (opcode == 6'h00) begin case (funct) - 6'h20: alu_oprn = 6'h01; // add - 6'h22: alu_oprn = 6'h02; // sub - 6'h2c: alu_oprn = 6'h03; // mul - 6'h02: alu_oprn = 6'h04; // srl - 6'h01: alu_oprn = 6'h05; // sll - 6'h24: alu_oprn = 6'h06; // and - 6'h25: alu_oprn = 6'h07; // or - 6'h27: alu_oprn = 6'h08; // nor - 6'h2a: alu_oprn = 6'h09; // slt + 6'h20: alu_oprn = `ALU_ADD; + 6'h22: alu_oprn = `ALU_SUB; + 6'h2c: alu_oprn = `ALU_MUL; + 6'h02: alu_oprn = `ALU_SRL; + 6'h01: alu_oprn = `ALU_SLL; + 6'h24: alu_oprn = `ALU_AND; + 6'h25: alu_oprn = `ALU_OR; + 6'h27: alu_oprn = `ALU_NOR; + 6'h2a: alu_oprn = `ALU_SLT; default: alu_oprn = 6'hxx; endcase end @@ -246,18 +274,18 @@ always @ (state) begin else begin case (opcode) // I-type - 6'h08: alu_oprn = 6'h01; // addi - 6'h1d: alu_oprn = 6'h03; // muli - 6'h0c: alu_oprn = 6'h06; // andi - 6'h0d: alu_oprn = 6'h07; // ori - 6'h0a: alu_oprn = 6'h09; // slti - 6'h04: alu_oprn = 6'h02; // beq - sub - 6'h05: alu_oprn = 6'h02; // bne - sub - 6'h23: alu_oprn = 6'h01; // lw - add - 6'h2b: alu_oprn = 6'h01; // sw - add + 6'h08: alu_oprn = `ALU_ADD; // addi + 6'h1d: alu_oprn = `ALU_MUL; // muli + 6'h0c: alu_oprn = `ALU_AND; // andi + 6'h0d: alu_oprn = `ALU_OR; // ori + 6'h0a: alu_oprn = `ALU_SLT; // slti + 6'h04: alu_oprn = `ALU_SUB; // beq - sub + 6'h05: alu_oprn = `ALU_SUB; // bne - sub + 6'h23: alu_oprn = `ALU_ADD; // lw - add + 6'h2b: alu_oprn = `ALU_ADD; // sw - add // J-type - 6'h1b: alu_oprn = 6'h02; // push - sub - 6'h1c: alu_oprn = 6'h01; // pop - add + 6'h1b: alu_oprn = `ALU_SUB; // push - sub + 6'h1c: alu_oprn = `ALU_ADD; // pop - add default: alu_oprn = 6'hxx; endcase end -- 2.47.2 From 1e1d0f0e0599b953d1276955897fdbc1c8186b9a Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Sun, 17 Nov 2024 01:14:29 -0800 Subject: [PATCH 08/18] project: track output --- OUTPUT/AND32_2x1_TB.out | 8 ++ OUTPUT/CS147_FL15_HW01_02_mem_dump.dat | 13 ++ OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat | 9 ++ OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat | 9 ++ OUTPUT/CS147_SP17_HW01_02_mem_dump.dat | 14 +++ OUTPUT/INV32_1x1_TB.out | 8 ++ OUTPUT/NOR32_2x1_TB.out | 8 ++ OUTPUT/OR32_2x1_TB.out | 8 ++ OUTPUT/RevFib_mem_dump.dat | 19 +++ OUTPUT/alu_tb.out | 147 ++++++++++++++++++++++ OUTPUT/barret_shifter_tb.out | 129 +++++++++++++++++++ OUTPUT/d_ff_tb.out | 10 ++ OUTPUT/d_latch_tb.out | 11 ++ OUTPUT/d_reg1_tb.out | 10 ++ OUTPUT/d_reg32_tb.out | 11 ++ OUTPUT/decoder_5x32_tb.out | 35 ++++++ OUTPUT/fibonacci_mem_dump.dat | 19 +++ OUTPUT/mux32_16x1_tb.out | 19 +++ OUTPUT/mux32_2x1_tb.out | 5 + OUTPUT/mux32_32x1_tb.out | 35 ++++++ OUTPUT/rf_tb.out | 67 ++++++++++ OUTPUT/sr_latch_tb.out | 17 +++ 22 files changed, 611 insertions(+) create mode 100755 OUTPUT/AND32_2x1_TB.out create mode 100644 OUTPUT/CS147_FL15_HW01_02_mem_dump.dat create mode 100644 OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat create mode 100644 OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat create mode 100644 OUTPUT/CS147_SP17_HW01_02_mem_dump.dat create mode 100755 OUTPUT/INV32_1x1_TB.out create mode 100755 OUTPUT/NOR32_2x1_TB.out create mode 100755 OUTPUT/OR32_2x1_TB.out create mode 100644 OUTPUT/RevFib_mem_dump.dat create mode 100644 OUTPUT/alu_tb.out create mode 100644 OUTPUT/barret_shifter_tb.out create mode 100644 OUTPUT/d_ff_tb.out create mode 100644 OUTPUT/d_latch_tb.out create mode 100644 OUTPUT/d_reg1_tb.out create mode 100644 OUTPUT/d_reg32_tb.out create mode 100644 OUTPUT/decoder_5x32_tb.out create mode 100644 OUTPUT/fibonacci_mem_dump.dat create mode 100644 OUTPUT/mux32_16x1_tb.out create mode 100644 OUTPUT/mux32_2x1_tb.out create mode 100644 OUTPUT/mux32_32x1_tb.out create mode 100644 OUTPUT/rf_tb.out create mode 100644 OUTPUT/sr_latch_tb.out diff --git a/OUTPUT/AND32_2x1_TB.out b/OUTPUT/AND32_2x1_TB.out new file mode 100755 index 0000000..dcf7ea5 --- /dev/null +++ b/OUTPUT/AND32_2x1_TB.out @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/AND32_2x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000000 +ffff0000 +0000ffff diff --git a/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat b/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat new file mode 100644 index 0000000..6b4ebd8 --- /dev/null +++ b/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat @@ -0,0 +1,13 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 diff --git a/OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat b/OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat new file mode 100644 index 0000000..2bf39c6 --- /dev/null +++ b/OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat @@ -0,0 +1,9 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 diff --git a/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat b/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat new file mode 100644 index 0000000..2bf39c6 --- /dev/null +++ b/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat @@ -0,0 +1,9 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 diff --git a/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat b/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat new file mode 100644 index 0000000..6e829de --- /dev/null +++ b/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat @@ -0,0 +1,14 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +0000000a +0000000b +0000000c +0000000d +0000000e +0000000f +00000010 +00000011 +00000012 +00000013 +00000000 diff --git a/OUTPUT/INV32_1x1_TB.out b/OUTPUT/INV32_1x1_TB.out new file mode 100755 index 0000000..776b89d --- /dev/null +++ b/OUTPUT/INV32_1x1_TB.out @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/INV32_1x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +0000ffff +ffffffff +5a5a5a5a +0000ffff +ffff0000 diff --git a/OUTPUT/NOR32_2x1_TB.out b/OUTPUT/NOR32_2x1_TB.out new file mode 100755 index 0000000..a7f6b39 --- /dev/null +++ b/OUTPUT/NOR32_2x1_TB.out @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/NOR32_2x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +ffffffff +00000000 +0000ffff +ffff0000 diff --git a/OUTPUT/OR32_2x1_TB.out b/OUTPUT/OR32_2x1_TB.out new file mode 100755 index 0000000..50bd555 --- /dev/null +++ b/OUTPUT/OR32_2x1_TB.out @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/OR32_2x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +ffffffff +00000000 +ffffffff +ffff0000 +0000ffff diff --git a/OUTPUT/RevFib_mem_dump.dat b/OUTPUT/RevFib_mem_dump.dat new file mode 100644 index 0000000..78993eb --- /dev/null +++ b/OUTPUT/RevFib_mem_dump.dat @@ -0,0 +1,19 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 diff --git a/OUTPUT/alu_tb.out b/OUTPUT/alu_tb.out new file mode 100644 index 0000000..1743837 --- /dev/null +++ b/OUTPUT/alu_tb.out @@ -0,0 +1,147 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/ALU_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000014 +00000001 +00000000 +00000001 +00000064 +00000001 +00000000 +00000001 +00002800 +00000001 +0000000a +00000001 +0000000a +00000001 +fffffff5 +00000000 +00000000 +00000001 +00000000 +00000001 +ffffffe2 +00000001 +ffffff1f +00000000 +0001ffff +00000000 +fff88000 +00000001 +00000001 +00000000 +ffffffff +00000000 +00000000 +00000001 +00000001 +00000000 +00000000 +00000001 +00000032 +00000001 +fffffd8f +00000000 +00000000 +00000001 +00000000 +00000001 +00000001 +00000000 +ffffffff +00000000 +00000000 +00000001 +00000000 +00000001 +ffffffc4 +00000001 +00000000 +00000001 +00000384 +00000001 +00000000 +00000001 +00000000 +00000001 +ffffffe2 +00000001 +ffffffe2 +00000001 +0000001d +00000000 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +ffffffff +00000000 +00000000 +00000001 +0000001b +00000000 +ffffffc7 +00000000 +fffffd8a +00000001 +00000000 +00000001 +00000000 +00000001 +00000020 +00000001 +fffffffb +00000000 +00000004 +00000001 +00000001 +00000000 +00000017 +00000000 +00000017 +00000000 +00000000 +00000001 +00000017 +00000000 +00000017 +00000000 +00000000 +00000001 +00000017 +00000000 +ffffffe8 +00000001 +00000000 +00000001 +00000046 +00000001 +ffffffba +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000046 +00000001 +ffffffb9 +00000000 +00000001 +00000000 diff --git a/OUTPUT/barret_shifter_tb.out b/OUTPUT/barret_shifter_tb.out new file mode 100644 index 0000000..b637103 --- /dev/null +++ b/OUTPUT/barret_shifter_tb.out @@ -0,0 +1,129 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/BARREL_SHIFTER32_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +4b4b4b4a +96969694 +2d2d2d28 +5a5a5a50 +b4b4b4a0 +69696940 +d2d2d280 +a5a5a500 +4b4b4a00 +96969400 +2d2d2800 +5a5a5000 +b4b4a000 +69694000 +d2d28000 +a5a50000 +4b4a0000 +96940000 +2d280000 +5a500000 +b4a00000 +69400000 +d2800000 +a5000000 +4a000000 +94000000 +28000000 +50000000 +a0000000 +40000000 +80000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +52d2d2d2 +29696969 +14b4b4b4 +0a5a5a5a +052d2d2d +02969696 +014b4b4b +00a5a5a5 +0052d2d2 +00296969 +0014b4b4 +000a5a5a +00052d2d +00029696 +00014b4b +0000a5a5 +000052d2 +00002969 +000014b4 +00000a5a +0000052d +00000296 +0000014b +000000a5 +00000052 +00000029 +00000014 +0000000a +00000005 +00000002 +00000001 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +xxxxxxxx +xxxxxxxx diff --git a/OUTPUT/d_ff_tb.out b/OUTPUT/d_ff_tb.out new file mode 100644 index 0000000..74f90af --- /dev/null +++ b/OUTPUT/d_ff_tb.out @@ -0,0 +1,10 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/D_FF_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000012 +00000013 +0000000b +00000017 +0000000d +0000000f +00000017 diff --git a/OUTPUT/d_latch_tb.out b/OUTPUT/d_latch_tb.out new file mode 100644 index 0000000..2ba4e87 --- /dev/null +++ b/OUTPUT/d_latch_tb.out @@ -0,0 +1,11 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/D_LATCH_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000022 +00000023 +00000027 +00000011 +00000013 +00000017 +0000002f +0000001b diff --git a/OUTPUT/d_reg1_tb.out b/OUTPUT/d_reg1_tb.out new file mode 100644 index 0000000..7a825ba --- /dev/null +++ b/OUTPUT/d_reg1_tb.out @@ -0,0 +1,10 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/REG1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000022 +00000023 +0000000b +0000002f +0000001d +0000001f +00000023 diff --git a/OUTPUT/d_reg32_tb.out b/OUTPUT/d_reg32_tb.out new file mode 100644 index 0000000..85f380e --- /dev/null +++ b/OUTPUT/d_reg32_tb.out @@ -0,0 +1,11 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/REG32_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +a5a5a5a5 +ffff0000 +00000000 +00000000 +0000ffff +0000ffff diff --git a/OUTPUT/decoder_5x32_tb.out b/OUTPUT/decoder_5x32_tb.out new file mode 100644 index 0000000..b944b99 --- /dev/null +++ b/OUTPUT/decoder_5x32_tb.out @@ -0,0 +1,35 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DECODER_5x32_TB/result +// format=bin addressradix=h dataradix=b version=1.0 wordsperline=1 noaddress +00000000000000000000000000000001 +00000000000000000000000000000010 +00000000000000000000000000000100 +00000000000000000000000000001000 +00000000000000000000000000010000 +00000000000000000000000000100000 +00000000000000000000000001000000 +00000000000000000000000010000000 +00000000000000000000000100000000 +00000000000000000000001000000000 +00000000000000000000010000000000 +00000000000000000000100000000000 +00000000000000000001000000000000 +00000000000000000010000000000000 +00000000000000000100000000000000 +00000000000000001000000000000000 +00000000000000010000000000000000 +00000000000000100000000000000000 +00000000000001000000000000000000 +00000000000010000000000000000000 +00000000000100000000000000000000 +00000000001000000000000000000000 +00000000010000000000000000000000 +00000000100000000000000000000000 +00000001000000000000000000000000 +00000010000000000000000000000000 +00000100000000000000000000000000 +00001000000000000000000000000000 +00010000000000000000000000000000 +00100000000000000000000000000000 +01000000000000000000000000000000 +10000000000000000000000000000000 diff --git a/OUTPUT/fibonacci_mem_dump.dat b/OUTPUT/fibonacci_mem_dump.dat new file mode 100644 index 0000000..78993eb --- /dev/null +++ b/OUTPUT/fibonacci_mem_dump.dat @@ -0,0 +1,19 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 diff --git a/OUTPUT/mux32_16x1_tb.out b/OUTPUT/mux32_16x1_tb.out new file mode 100644 index 0000000..3c916bd --- /dev/null +++ b/OUTPUT/mux32_16x1_tb.out @@ -0,0 +1,19 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/MUX32_16x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000001 +00000002 +00000003 +00000004 +00000005 +00000006 +00000007 +00000008 +00000009 +0000000a +0000000b +0000000c +0000000d +0000000e +0000000f diff --git a/OUTPUT/mux32_2x1_tb.out b/OUTPUT/mux32_2x1_tb.out new file mode 100644 index 0000000..e39c575 --- /dev/null +++ b/OUTPUT/mux32_2x1_tb.out @@ -0,0 +1,5 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/MUX32_2x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +a5a5a5a5 +5a5a5a5a diff --git a/OUTPUT/mux32_32x1_tb.out b/OUTPUT/mux32_32x1_tb.out new file mode 100644 index 0000000..a7a230c --- /dev/null +++ b/OUTPUT/mux32_32x1_tb.out @@ -0,0 +1,35 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/MUX32_32x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000001 +00000002 +00000003 +00000004 +00000005 +00000006 +00000007 +00000008 +00000009 +0000000a +0000000b +0000000c +0000000d +0000000e +0000000f +00000010 +00000011 +00000012 +00000013 +00000014 +00000015 +00000016 +00000017 +00000018 +00000019 +0000001a +0000001b +0000001c +0000001d +0000001e +0000001f diff --git a/OUTPUT/rf_tb.out b/OUTPUT/rf_tb.out new file mode 100644 index 0000000..26a2999 --- /dev/null +++ b/OUTPUT/rf_tb.out @@ -0,0 +1,67 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/RF_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +0000000a +00000014 +0000001e +00000028 +00000032 +0000003c +00000046 +00000050 +0000005a +00000064 +0000006e +00000078 +00000082 +0000008c +00000096 +000000a0 +000000aa +000000b4 +000000be +000000c8 +000000d2 +000000dc +000000e6 +000000f0 +000000fa +00000104 +0000010e +00000118 +00000122 +0000012c +00000136 +00000014 +00000014 +00000014 +00000014 +00000014 +00000014 +00000014 +00000014 +00000014 +00000014 +00000014 +00000014 +00000014 +00000014 +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx +xxxxxxxx diff --git a/OUTPUT/sr_latch_tb.out b/OUTPUT/sr_latch_tb.out new file mode 100644 index 0000000..e0379d2 --- /dev/null +++ b/OUTPUT/sr_latch_tb.out @@ -0,0 +1,17 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/SR_LATCH_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000042 +00000043 +00000047 +0000004b +0000004f +00000021 +00000023 +00000027 +0000002b +0000002f +0000005b +00000053 +00000037 +00000033 -- 2.47.2 From 9e6d1d5df27ca8e5682b0f2e17a8602fb7ca7f5c Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Sun, 17 Nov 2024 02:30:25 -0800 Subject: [PATCH 09/18] control unit: ctrl signal refactor --- control_unit.v | 263 ++++++++++++++++++++++++------------------------- 1 file changed, 128 insertions(+), 135 deletions(-) diff --git a/control_unit.v b/control_unit.v index e9321b4..ad18923 100644 --- a/control_unit.v +++ b/control_unit.v @@ -19,6 +19,42 @@ //------------------------------------------------------------------------------------------ `include "prj_definition.v" +// Control signals, same as in data_path.v +`define pc_load 0 +`define pc_sel_1 1 +`define pc_sel_2 2 +`define pc_sel_3 3 + +`define ir_load 4 + +`define r1_sel_1 5 +`define reg_r 6 +`define reg_w 7 + +`define sp_load 8 + +`define op1_sel_1 9 +`define op2_sel_1 10 +`define op2_sel_2 11 +`define op2_sel_3 12 +`define op2_sel_4 13 + +`define alu_oprn 19:14 + +`define ma_sel_1 20 +`define ma_sel_2 21 + +`define md_sel_1 22 + +`define wd_sel_1 23 +`define wd_sel_2 24 +`define wd_sel_3 25 + +`define wa_sel_1 26 +`define wa_sel_2 27 +`define wa_sel_3 28 + +// ALU operation codes `define ALU_ADD 6'h01 `define ALU_SUB 6'h02 `define ALU_MUL 6'h03 @@ -29,28 +65,29 @@ `define ALU_NOR 6'h08 `define ALU_SLT 6'h09 +// Instruction opcodes `define OP_RTYPE 6'h00 -`define FN_ADD 6'h20 -`define FN_SUB 6'h22 -`define FN_MUL 6'h2c -`define FN_AND 6'h24 -`define FN_OR 6'h25 -`define FN_NOR 6'h27 -`define FN_SLT 6'h2a -`define FN_SLL 6'h01 -`define FN_SRL 6'h02 -`define FN_JR 6'h08 +`define FN_ADD 6'h20 +`define FN_SUB 6'h22 +`define FN_MUL 6'h2c +`define FN_AND 6'h24 +`define FN_OR 6'h25 +`define FN_NOR 6'h27 +`define FN_SLT 6'h2a +`define FN_SLL 6'h01 +`define FN_SRL 6'h02 +`define FN_JR 6'h08 `define OP_ADDI 6'h08 `define OP_MULI 6'h1d `define OP_ANDI 6'h0c -`define OP_ORI 6'h0d -`define OP_LUI 6'h0f +`define OP_ORI 6'h0d +`define OP_LUI 6'h0f `define OP_SLTI 6'h0a -`define OP_BEQ 6'h04 -`define OP_BNE 6'h05 -`define OP_LW 6'h23 -`define OP_SW 6'h2b +`define OP_BEQ 6'h04 +`define OP_BNE 6'h05 +`define OP_LW 6'h23 +`define OP_SW 6'h2b module CONTROL_UNIT(CTRL, READ, WRITE, ZERO, INSTRUCTION, CLK, RST); // Output signals @@ -90,7 +127,7 @@ case(opcode2) 6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); 6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); 6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); 6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); 6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); 6'h01: $write("sll r[%02d], r[%02d], %2d;", rd2, rs2, shamt2); @@ -126,56 +163,12 @@ endtask reg read, write; -assign READ = read; -assign WRITE = write; +buf (READ, read); +buf (WRITE, write); -// Control signals, same as in data_path.v -reg pc_load, pc_sel_1, pc_sel_2, pc_sel_3, - ir_load, reg_r, reg_w, - r1_sel_1, wa_sel_1, wa_sel_2, wa_sel_3, +reg [31:0] C; - sp_load, op1_sel_1, - op2_sel_1, op2_sel_2, op2_sel_3, op2_sel_4, - - wd_sel_1, wd_sel_2, wd_sel_3, - ma_sel_1, ma_sel_2, - md_sel_1; - -reg [5:0] alu_oprn; - -buf (CTRL[0], pc_load); -buf (CTRL[1], pc_sel_1); -buf (CTRL[2], pc_sel_2); -buf (CTRL[3], pc_sel_3); - -buf (CTRL[4], ir_load); - -buf (CTRL[5], r1_sel_1); -buf (CTRL[6], reg_r); -buf (CTRL[7], reg_w); - -buf (CTRL[8], sp_load); - -buf (CTRL[9], op1_sel_1); -buf (CTRL[10], op2_sel_1); -buf (CTRL[11], op2_sel_2); -buf (CTRL[12], op2_sel_3); -buf (CTRL[13], op2_sel_4); - -buf alu_oprn_buf [5:0] (CTRL[19:14], alu_oprn); - -buf (CTRL[20], ma_sel_1); -buf (CTRL[21], ma_sel_2); - -buf (CTRL[22], md_sel_1); - -buf (CTRL[23], wd_sel_1); -buf (CTRL[24], wd_sel_2); -buf (CTRL[25], wd_sel_3); - -buf (CTRL[26], wa_sel_1); -buf (CTRL[27], wa_sel_2); -buf (CTRL[28], wa_sel_3); +buf ctrl_buf [31:0] (CTRL, C); // Parse the instruction data reg [5:0] opcode; @@ -201,124 +194,133 @@ always @ (state) begin {opcode, addr} = INSTRUCTION; // Print current state - $write("@ %6dns -> ", $time); - $write("STATE ", state, ": "); - case (state) - `PROC_FETCH: $write("FETCH"); - `PROC_DECODE: $write("DECODE"); - `PROC_EXE: $write("EXECUTE"); - `PROC_MEM: $write("MEMORY"); - `PROC_WB: $write("WRITE BACK"); - default: $write("INVALID"); - endcase - $write("\n"); +// $write("@ %6dns -> ", $time); +// $write("STATE ", state, ": "); +// case (state) +// `PROC_FETCH: $write("FETCH"); +// `PROC_DECODE: $write("DECODE"); +// `PROC_EXE: $write("EXECUTE"); +// `PROC_MEM: $write("MEMORY"); +// `PROC_WB: $write("WRITE BACK"); +// default: $write("INVALID"); +// endcase +// $write("\n"); case (state) // fetch - next instruction from memory at PC `PROC_FETCH: begin + print_instruction(INSTRUCTION); + // set everything in ctrl to 0 + C = 32'b0; + // loaded in previous state, set to 0 - pc_load = 1'b0; - reg_r = 1'b0; - reg_w = 1'b0; + C[`pc_load] = 1'b0; + C[`sp_load] = 1'b0; + C[`reg_r] = 1'b0; + C[`reg_w] = 1'b0; // load now - ir_load = 1'b1; + // TODO: ir_load should not be 1 here + C[`ir_load] = 1'b1; read = 1'b1; write = 1'b0; // selections // ma_sel_2 - load data from mem[PC] - ma_sel_2 = 1'b1; + C[`ma_sel_1] = 1'b0; + C[`ma_sel_2] = 1'b1; end // decode - parse instruction and read values from register file `PROC_DECODE: begin // loaded in previous state, set to 0 - ir_load = 1'b0; - sp_load = 1'b0; + C[`sp_load] = 1'b0; read = 1'b0; // load now - reg_r = 1'b1; - reg_w = 1'b0; + C[`ir_load] = 1'b1; + C[`reg_r] = 1'b1; + C[`reg_w] = 1'b0; // selections // r1_sel_1: push - store value of r0 at stack pointer - r1_sel_1 = opcode != 6'h1b ? 1'b0 : 1'b1; + C[`r1_sel_1] = opcode != 6'h1b ? 1'b0 : 1'b1; // wa_sel_1: R-type - write to rd, I-type - write to rt - wa_sel_1 = opcode == 6'h00 ? 1'b0 : 1'b1; + C[`wa_sel_1] = opcode == 6'h00 ? 1'b0 : 1'b1; // wa_sel_2: jal - write to r31, pop - write to r0 - wa_sel_2 = opcode == 6'h03 ? 1'b1 : 1'b0; + C[`wa_sel_2] = opcode == 6'h03 ? 1'b1 : 1'b0; // wa_sel_3: push or pop - wa_sel_2, else wa_sel_1 - wa_sel_3 = opcode == 6'h03 || opcode == 6'h1c ? 1'b0 : 1'b1; + C[`wa_sel_3] = opcode == 6'h03 || opcode == 6'h1c ? 1'b0 : 1'b1; // jr - jump to address in register - pc_sel_1 = opcode == 6'h00 && funct == 6'h08 ? 1'b0 : 1'b1; + C[`pc_sel_1] = opcode == 6'h00 && funct == 6'h08 ? 1'b0 : 1'b1; // beq, bne - branch if equal or not equal // TODO: this should only be selected if the condition is met // pc_sel_2 = opcode == 6'h04 || opcode == 6'h05 ? 1'b1 : 1'b0; // jmp, jal - jump to address - pc_sel_3 = opcode == 6'h02 || opcode == 6'h03 ? 1'b0 : 1'b1; + C[`pc_sel_3] = opcode == 6'h02 || opcode == 6'h03 ? 1'b0 : 1'b1; // alu_oprn - operation to be performed by ALU // R-type if (opcode == 6'h00) begin case (funct) - 6'h20: alu_oprn = `ALU_ADD; - 6'h22: alu_oprn = `ALU_SUB; - 6'h2c: alu_oprn = `ALU_MUL; - 6'h02: alu_oprn = `ALU_SRL; - 6'h01: alu_oprn = `ALU_SLL; - 6'h24: alu_oprn = `ALU_AND; - 6'h25: alu_oprn = `ALU_OR; - 6'h27: alu_oprn = `ALU_NOR; - 6'h2a: alu_oprn = `ALU_SLT; - default: alu_oprn = 6'hxx; + 6'h20: C[`alu_oprn] = `ALU_ADD; + 6'h22: C[`alu_oprn] = `ALU_SUB; + 6'h2c: C[`alu_oprn] = `ALU_MUL; + 6'h02: C[`alu_oprn] = `ALU_SRL; + 6'h01: C[`alu_oprn] = `ALU_SLL; + 6'h24: C[`alu_oprn] = `ALU_AND; + 6'h25: C[`alu_oprn] = `ALU_OR; + 6'h27: C[`alu_oprn] = `ALU_NOR; + 6'h2a: C[`alu_oprn] = `ALU_SLT; + default: C[`alu_oprn] = 6'h00; endcase end // I-type and J-type else begin case (opcode) // I-type - 6'h08: alu_oprn = `ALU_ADD; // addi - 6'h1d: alu_oprn = `ALU_MUL; // muli - 6'h0c: alu_oprn = `ALU_AND; // andi - 6'h0d: alu_oprn = `ALU_OR; // ori - 6'h0a: alu_oprn = `ALU_SLT; // slti - 6'h04: alu_oprn = `ALU_SUB; // beq - sub - 6'h05: alu_oprn = `ALU_SUB; // bne - sub - 6'h23: alu_oprn = `ALU_ADD; // lw - add - 6'h2b: alu_oprn = `ALU_ADD; // sw - add + 6'h08: C[`alu_oprn] = `ALU_ADD; // addi + 6'h1d: C[`alu_oprn] = `ALU_MUL; // muli + 6'h0c: C[`alu_oprn] = `ALU_AND; // andi + 6'h0d: C[`alu_oprn] = `ALU_OR; // ori + 6'h0a: C[`alu_oprn] = `ALU_SLT; // slti + 6'h04: C[`alu_oprn] = `ALU_SUB; // beq - sub + 6'h05: C[`alu_oprn] = `ALU_SUB; // bne - sub + 6'h23: C[`alu_oprn] = `ALU_ADD; // lw - add + 6'h2b: C[`alu_oprn] = `ALU_ADD; // sw - add // J-type - 6'h1b: alu_oprn = `ALU_SUB; // push - sub - 6'h1c: alu_oprn = `ALU_ADD; // pop - add - default: alu_oprn = 6'hxx; + 6'h1b: C[`alu_oprn] = `ALU_SUB; // push - sub + 6'h1c: C[`alu_oprn] = `ALU_ADD; // pop - add + default: C[`alu_oprn] = 6'h00; endcase end // op1_sel_1 - select r1 or sp based on opcode // push or pop - sp, else r1 - op1_sel_1 = opcode == 6'h1b || opcode == 6'h1c ? 1'b1 : 1'b0; + C[`op1_sel_1] = opcode == 6'h1b || opcode == 6'h1c ? 1'b1 : 1'b0; // op2_sel_1 - select 1 or shamt based on alu_oprn // sll or srl - shamt, else 1 (for increments/decrements) - op2_sel_1 = alu_oprn == 6'h04 || alu_oprn == 6'h05 ? 1'b1 : 1'b0; + C[`op2_sel_1] = C[`alu_oprn] == 6'h04 || C[`alu_oprn] == 6'h05 ? 1'b1 : 1'b0; // op2_sel_2 - select imm_zx or imm_sx based on alu_oprn // logical (and, or) - imm_zx, else imm_sx; ('nor' not availble in I-type) - op2_sel_2 = alu_oprn == 6'h06 || alu_oprn == 6'h07 ? 1'b0 : 1'b1; + C[`op2_sel_2] = C[`alu_oprn] == 6'h06 || C[`alu_oprn] == 6'h07 ? 1'b0 : 1'b1; // op2_sel_3 - select op2_sel_2 or op2_sel_1 based on alu_oprn // R-type - op2_sel_1, I-type - op2_sel_2 - op2_sel_3 = opcode == 6'h00 ? 1'b1 : 1'b0; + C[`op2_sel_3] = opcode == 6'h00 ? 1'b1 : 1'b0; // op2_sel_4 - select op2_sel_3 or r2 // I-type or shift or inc/dec - op2_sel_3, else r2 // i.e. r2 only if R-type and not shift - op2_sel_4 = opcode != 6'h00 || alu_oprn == 6'h04 || alu_oprn == 6'h05 ? 1'b0 : 1'b1; + C[`op2_sel_4] = opcode != 6'h00 || C[`alu_oprn] == 6'h04 || C[`alu_oprn] == 6'h05 ? 1'b0 : 1'b1; end // execute - perform operation based on instruction `PROC_EXE: begin + // loaded in previous state, set to 0 + C[`ir_load] = 1'b0; // selections // wd_sel_1 - alu_out or DATA_IN - wd_sel_1 = 1'b0; + C[`wd_sel_1] = 1'b0; // wd_sel_2 - wd_sel_1 or imm_zx_lsb // lui - imm_zx_lsb, else wd_sel_1 - wd_sel_2 = opcode == 6'h0f ? 1'b1 : 1'b0; + C[`wd_sel_2] = opcode == 6'h0f ? 1'b1 : 1'b0; // wd_sel_3 - pc_inc or wd_sel_2 // jal - pc_inc, else wd_sel_2 - wd_sel_3 = opcode == 6'h03 ? 1'b0 : 1'b1; + C[`wd_sel_3] = opcode == 6'h03 ? 1'b0 : 1'b1; // md_sel_1 - r1 for push, r2 for sw - md_sel_1 = opcode == 6'h1b ? 1'b1 : 1'b0; + C[`md_sel_1] = opcode == 6'h1b ? 1'b1 : 1'b0; end `PROC_MEM: begin // load now @@ -337,32 +339,23 @@ always @ (state) begin read = 1'b0; write = 1'b0; // load now - pc_load = 1'b1; + C[`pc_load] = 1'b1; // write to register file if // R-type (except jr) or I-type (except beq, bne, sw) or pop or jal - reg_w = (opcode == 6'h00 && funct != 6'h08) // R-type (except jr) + C[`reg_w] = (opcode == 6'h00 && funct != 6'h08) // R-type (except jr) || (opcode == 6'h08 || opcode == 6'h1d || opcode == 6'h0c || opcode == 6'h0d || opcode == 6'h0f || opcode == 6'h0a || opcode == 6'h23) // I-type (except beq, bne, sw) || (opcode == 6'h1c || opcode == 6'h03) // pop or jal ? 1'b1 : 1'b0; // selections // ma_sel_2 - load data from mem[PC] - ma_sel_2 = 1'b1; + C[`ma_sel_2] = 1'b1; // pc_sel_2 - branch if equal or not equal - pc_sel_2 = (opcode == 6'h04 && ZERO) || (opcode == 6'h05 && ~ZERO) ? 1'b1 : 1'b0; + C[`pc_sel_2] = (opcode == 6'h04 && ZERO) || (opcode == 6'h05 && ~ZERO) ? 1'b1 : 1'b0; end - default: begin - $write("@ %6dns -> ", $time); - $write("STATE ", state, ": "); - $write("INVALID"); - print_instruction(INSTRUCTION); - end endcase - // TBD - assign control signals based on instruction - print_instruction(INSTRUCTION); - // TBD - assign READ and WRITE signals based on instruction end endmodule -- 2.47.2 From 5d64b65212bf9b925221995b2c74cdff6adb1645 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Sun, 17 Nov 2024 02:38:11 -0800 Subject: [PATCH 10/18] data path: replace instruction register with D-latch --- control_unit.v | 3 +-- data_path.v | 2 +- logic.v | 23 +++++++++++++++++------ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/control_unit.v b/control_unit.v index ad18923..aafa85c 100644 --- a/control_unit.v +++ b/control_unit.v @@ -215,12 +215,11 @@ always @ (state) begin // loaded in previous state, set to 0 C[`pc_load] = 1'b0; + C[`ir_load] = 1'b0; C[`sp_load] = 1'b0; C[`reg_r] = 1'b0; C[`reg_w] = 1'b0; // load now - // TODO: ir_load should not be 1 here - C[`ir_load] = 1'b1; read = 1'b1; write = 1'b0; // selections diff --git a/data_path.v b/data_path.v index ba9b54b..1c9474f 100644 --- a/data_path.v +++ b/data_path.v @@ -113,7 +113,7 @@ buf addr_buf [25:0] (addr, ir[25:0]); // Instruction Register input // Instruction Register -REG32 ir_inst(.Q(ir), .D(DATA_IN), .LOAD(ir_load), .CLK(CLK), .RESET(RST)); +D_LATCH32 ir_inst(.Q(ir), .D(DATA_IN), .LOAD(ir_load), .RESET(RST)); // Register File Input wire [31:0] r1_sel, wa_sel, wd_sel; diff --git a/logic.v b/logic.v index a1b73ad..ddb5567 100644 --- a/logic.v +++ b/logic.v @@ -13,6 +13,23 @@ // 1.0 Sep 02, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation //------------------------------------------------------------------------------------------ // + +// 32-bit D latch +module D_LATCH32(Q, D, LOAD, RESET); +output [31:0] Q; + +input LOAD; +input [31:0] D; +input RESET; + +genvar i; +generate + for (i = 0; i < 32; i = i + 1) begin : d_latch_gen + D_LATCH d_latch_inst(Q[i], _, D[i], LOAD, 1'b1, RESET); + end +endgenerate +endmodule + // 64-bit two's complement module TWOSCOMP64(Y,A); //output list @@ -56,7 +73,6 @@ generate REG1 reg_inst(.Q(Q[i]), .Qbar(qbar[i]), .D(D[i]), .L(LOAD), .C(CLK), .nP(RESET), .nR(1'b1)); end endgenerate - endmodule // 32-bit registere +ve edge, Reset on RESET=0 @@ -73,7 +89,6 @@ generate REG1 r(Q[i], _, D[i], LOAD, CLK, 1'b1, RESET); end endgenerate - endmodule // 1 bit register +ve edge, @@ -164,7 +179,6 @@ generate and msb1(D[i + 16], I[4], half[i]); end endgenerate - endmodule // 4x16 Line decoder @@ -187,8 +201,6 @@ generate and msb1(D[i + 8], I[3], half[i]); end endgenerate - - endmodule // 3x8 Line decoder @@ -211,7 +223,6 @@ generate and msb1(D[i + 4], I[2], half[i]); end endgenerate - endmodule // 2x4 Line decoder -- 2.47.2 From 05c950a0f8f7bd2e44c22f160dd892d13a2c40ab Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Sun, 17 Nov 2024 04:19:03 -0800 Subject: [PATCH 11/18] control unit: progress --- control_unit.v | 160 +++++++++++++++++++++++-------------------------- data_path.v | 6 +- 2 files changed, 78 insertions(+), 88 deletions(-) diff --git a/control_unit.v b/control_unit.v index aafa85c..aa9ea8d 100644 --- a/control_unit.v +++ b/control_unit.v @@ -55,6 +55,7 @@ `define wa_sel_3 28 // ALU operation codes +`define ALU_NOP 6'h00 `define ALU_ADD 6'h01 `define ALU_SUB 6'h02 `define ALU_MUL 6'h03 @@ -66,6 +67,7 @@ `define ALU_SLT 6'h09 // Instruction opcodes +// R-type `define OP_RTYPE 6'h00 `define FN_ADD 6'h20 `define FN_SUB 6'h22 @@ -77,7 +79,7 @@ `define FN_SLL 6'h01 `define FN_SRL 6'h02 `define FN_JR 6'h08 - +// I-type `define OP_ADDI 6'h08 `define OP_MULI 6'h1d `define OP_ANDI 6'h0c @@ -88,6 +90,11 @@ `define OP_BNE 6'h05 `define OP_LW 6'h23 `define OP_SW 6'h2b +// J-type +`define OP_JMP 6'h02 +`define OP_JAL 6'h03 +`define OP_PUSH 6'h1b +`define OP_POP 6'h1c module CONTROL_UNIT(CTRL, READ, WRITE, ZERO, INSTRUCTION, CLK, RST); // Output signals @@ -121,39 +128,38 @@ $write("@ %6dns -> [0X%08h] ", $time, inst); case(opcode2) // R-Type -6'h00 : begin - case(funct2) - 6'h20: $write("add r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h01: $write("sll r[%02d], r[%02d], %2d;", rd2, rs2, shamt2); - 6'h02: $write("srl r[%02d], 0X%02h, r[%02d];", rd2, rs2, shamt2); - 6'h08: $write("jr r[%02d];", rs2); - default: begin $write(""); - end - endcase - end -// I-type -6'h08 : $write("addi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); -6'h1d : $write("muli r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); -6'h0c : $write("andi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); -6'h0d : $write("ori r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); -6'h0f : $write("lui r[%02d], 0X%04h;", rt2, immediate2); -6'h0a : $write("slti r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); -6'h04 : $write("beq r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); -6'h05 : $write("bne r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); -6'h23 : $write("lw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); -6'h2b : $write("sw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); -// J-Type -6'h02 : $write("jmp 0X%07h;", address2); -6'h03 : $write("jal 0X%07h;", address2); -6'h1b : $write("push;"); -6'h1c : $write("pop;"); -default: $write(""); + 6'h00 : begin + case(funct2) + 6'h20: $write("add r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); + 6'h01: $write("sll r[%02d], r[%02d], %2d;", rd2, rs2, shamt2); + 6'h02: $write("srl r[%02d], 0X%02h, r[%02d];", rd2, rs2, shamt2); + 6'h08: $write("jr r[%02d];", rs2); + default: $write(""); + endcase + end + // I-type + 6'h08 : $write("addi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); + 6'h1d : $write("muli r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); + 6'h0c : $write("andi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); + 6'h0d : $write("ori r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); + 6'h0f : $write("lui r[%02d], 0X%04h;", rt2, immediate2); + 6'h0a : $write("slti r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); + 6'h04 : $write("beq r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); + 6'h05 : $write("bne r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); + 6'h23 : $write("lw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); + 6'h2b : $write("sw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); + // J-Type + 6'h02 : $write("jmp 0X%07h;", address2); + 6'h03 : $write("jal 0X%07h;", address2); + 6'h1b : $write("push;"); + 6'h1c : $write("pop;"); + default: $write(""); endcase $write("\n"); @@ -209,33 +215,27 @@ always @ (state) begin case (state) // fetch - next instruction from memory at PC `PROC_FETCH: begin - print_instruction(INSTRUCTION); // set everything in ctrl to 0 C = 32'b0; - - // loaded in previous state, set to 0 - C[`pc_load] = 1'b0; - C[`ir_load] = 1'b0; - C[`sp_load] = 1'b0; - C[`reg_r] = 1'b0; - C[`reg_w] = 1'b0; - // load now + // memory read = 1'b1; write = 1'b0; // selections - // ma_sel_2 - load data from mem[PC] - C[`ma_sel_1] = 1'b0; - C[`ma_sel_2] = 1'b1; + C[`ma_sel_2] = 1'b1; // load data from mem[PC] end // decode - parse instruction and read values from register file `PROC_DECODE: begin // loaded in previous state, set to 0 - C[`sp_load] = 1'b0; read = 1'b0; // load now C[`ir_load] = 1'b1; C[`reg_r] = 1'b1; - C[`reg_w] = 1'b0; + end + // execute - perform operation based on instruction + `PROC_EXE: begin + print_instruction(INSTRUCTION); + // loaded in previous state, set to 0 + C[`ir_load] = 1'b0; // selections // r1_sel_1: push - store value of r0 at stack pointer C[`r1_sel_1] = opcode != 6'h1b ? 1'b0 : 1'b1; @@ -251,41 +251,41 @@ always @ (state) begin // TODO: this should only be selected if the condition is met // pc_sel_2 = opcode == 6'h04 || opcode == 6'h05 ? 1'b1 : 1'b0; // jmp, jal - jump to address - C[`pc_sel_3] = opcode == 6'h02 || opcode == 6'h03 ? 1'b0 : 1'b1; + C[`pc_sel_3] = opcode == `OP_JMP || opcode == `OP_JAL ? 1'b0 : 1'b1; // alu_oprn - operation to be performed by ALU // R-type - if (opcode == 6'h00) begin + if (opcode == `OP_RTYPE) begin case (funct) - 6'h20: C[`alu_oprn] = `ALU_ADD; - 6'h22: C[`alu_oprn] = `ALU_SUB; - 6'h2c: C[`alu_oprn] = `ALU_MUL; - 6'h02: C[`alu_oprn] = `ALU_SRL; - 6'h01: C[`alu_oprn] = `ALU_SLL; - 6'h24: C[`alu_oprn] = `ALU_AND; - 6'h25: C[`alu_oprn] = `ALU_OR; - 6'h27: C[`alu_oprn] = `ALU_NOR; - 6'h2a: C[`alu_oprn] = `ALU_SLT; - default: C[`alu_oprn] = 6'h00; + `FN_ADD: C[`alu_oprn] = `ALU_ADD; + `FN_SUB: C[`alu_oprn] = `ALU_SUB; + `FN_MUL: C[`alu_oprn] = `ALU_MUL; + `FN_SRL: C[`alu_oprn] = `ALU_SRL; + `FN_SLL: C[`alu_oprn] = `ALU_SLL; + `FN_AND: C[`alu_oprn] = `ALU_AND; + `FN_OR: C[`alu_oprn] = `ALU_OR; + `FN_NOR: C[`alu_oprn] = `ALU_NOR; + `FN_SLT: C[`alu_oprn] = `ALU_SLT; + default: C[`alu_oprn] = `ALU_NOP; endcase end // I-type and J-type else begin case (opcode) // I-type - 6'h08: C[`alu_oprn] = `ALU_ADD; // addi - 6'h1d: C[`alu_oprn] = `ALU_MUL; // muli - 6'h0c: C[`alu_oprn] = `ALU_AND; // andi - 6'h0d: C[`alu_oprn] = `ALU_OR; // ori - 6'h0a: C[`alu_oprn] = `ALU_SLT; // slti - 6'h04: C[`alu_oprn] = `ALU_SUB; // beq - sub - 6'h05: C[`alu_oprn] = `ALU_SUB; // bne - sub - 6'h23: C[`alu_oprn] = `ALU_ADD; // lw - add - 6'h2b: C[`alu_oprn] = `ALU_ADD; // sw - add + `OP_ADDI: C[`alu_oprn] = `ALU_ADD; // addi + `OP_MULI: C[`alu_oprn] = `ALU_MUL; // muli + `OP_ANDI: C[`alu_oprn] = `ALU_AND; // andi + `OP_ORI: C[`alu_oprn] = `ALU_OR; // ori + `OP_SLTI: C[`alu_oprn] = `ALU_SLT; // slti + `OP_BEQ: C[`alu_oprn] = `ALU_SUB; // beq - sub + `OP_BNE: C[`alu_oprn] = `ALU_SUB; // bne - sub + `OP_LW: C[`alu_oprn] = `ALU_ADD; // lw - add + `OP_SW: C[`alu_oprn] = `ALU_ADD; // sw - add // J-type - 6'h1b: C[`alu_oprn] = `ALU_SUB; // push - sub - 6'h1c: C[`alu_oprn] = `ALU_ADD; // pop - add - default: C[`alu_oprn] = 6'h00; + `OP_PUSH: C[`alu_oprn] = `ALU_SUB; // push - sub + `OP_POP: C[`alu_oprn] = `ALU_ADD; // pop - add + default: C[`alu_oprn] = `ALU_NOP; endcase end // op1_sel_1 - select r1 or sp based on opcode @@ -304,12 +304,7 @@ always @ (state) begin // I-type or shift or inc/dec - op2_sel_3, else r2 // i.e. r2 only if R-type and not shift C[`op2_sel_4] = opcode != 6'h00 || C[`alu_oprn] == 6'h04 || C[`alu_oprn] == 6'h05 ? 1'b0 : 1'b1; - end - // execute - perform operation based on instruction - `PROC_EXE: begin - // loaded in previous state, set to 0 - C[`ir_load] = 1'b0; - // selections + // wd_sel_1 - alu_out or DATA_IN C[`wd_sel_1] = 1'b0; // wd_sel_2 - wd_sel_1 or imm_zx_lsb @@ -329,8 +324,8 @@ always @ (state) begin write = 1'b1; end else begin - read = 1'b1; - write = 1'b0; +// read = 1'b1; +// write = 1'b0; end end `PROC_WB: begin @@ -347,16 +342,12 @@ always @ (state) begin || (opcode == 6'h1c || opcode == 6'h03) // pop or jal ? 1'b1 : 1'b0; // selections - // ma_sel_2 - load data from mem[PC] - C[`ma_sel_2] = 1'b1; // pc_sel_2 - branch if equal or not equal C[`pc_sel_2] = (opcode == 6'h04 && ZERO) || (opcode == 6'h05 && ~ZERO) ? 1'b1 : 1'b0; end endcase - end - endmodule @@ -404,5 +395,4 @@ always @ (posedge CLK) begin end assign STATE = state_sel; - endmodule diff --git a/data_path.v b/data_path.v index 1c9474f..4ec4653 100644 --- a/data_path.v +++ b/data_path.v @@ -149,11 +149,11 @@ ALU alu_inst(.OUT(alu_out), .ZERO(ZERO), .OP1(op1_sel), .OP2(op2_sel), .OPRN(alu // Progam Counter Input wire [31:0] pc_sel; -wire [31:0] pc_offset, pc_jump, pc_sel_p1, pc_sel_p2; +wire [31:0] pc_branch, pc_jump, pc_sel_p1, pc_sel_p2; RC_ADD_SUB_32 pc_inc_inst(.Y(pc_inc), .CO(), .A(pc), .B(32'b1), .SnA(1'b0)); MUX32_2x1 mux_pc_sel_p1(pc_sel_p1, r1, pc_inc, pc_sel_1); -RC_ADD_SUB_32 pc_sel_2_inst(.Y(pc_offset), .CO(), .A(pc), .B(imm_sx), .SnA(1'b0)); -MUX32_2x1 mux_pc_sel_p2(pc_sel_p2, pc_sel_p1, pc_offset, pc_sel_2); +RC_ADD_SUB_32 pc_sel_2_inst(.Y(pc_branch), .CO(), .A(pc), .B(imm_sx), .SnA(1'b0)); +MUX32_2x1 mux_pc_sel_p2(pc_sel_p2, pc_sel_p1, pc_branch, pc_sel_2); buf pc_jump_buf [31:0] (pc_jump, {6'b0, addr}); MUX32_2x1 mux_pc_sel(pc_sel, pc_jump, pc_sel_p2, pc_sel_3); // Program Counter -- 2.47.2 From 2ffd8c9424b5d3f7e7d4993d46687ad232bbe0da Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Mon, 18 Nov 2024 00:46:22 -0800 Subject: [PATCH 12/18] da vinci tb: patch for smaller (20-bit) memory for faster tests --- TESTBENCH/da_vinci_tb.v | 12 ++++---- TESTPROGRAM/CS147_FL15_HW01_02.dat | 44 +++++++++++++++--------------- TESTPROGRAM/CS147_SP15_HW01_02.dat | 2 +- TESTPROGRAM/CS147_SP17_HW01_02.dat | 24 ++++++++-------- TESTPROGRAM/fibonacci.dat | 2 +- prj_definition.v | 4 +-- 6 files changed, 44 insertions(+), 44 deletions(-) diff --git a/TESTBENCH/da_vinci_tb.v b/TESTBENCH/da_vinci_tb.v index 49b534b..9e8cde2 100644 --- a/TESTBENCH/da_vinci_tb.v +++ b/TESTBENCH/da_vinci_tb.v @@ -62,7 +62,7 @@ begin #5000 $write("\n"); $write("===> Done simulating fibonacci.dat\n", ""); $write("\n"); - $writememh("./OUTPUT/fibonacci_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h01000000, 'h0100000f); + $writememh("./OUTPUT/fibonacci_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h00040000, 'h0004000f); /* END : test 1*/ end @@ -78,7 +78,7 @@ begin #5000 $write("\n"); $write("===> Done simulating RevFib.dat\n", ""); $write("\n"); - $writememh("./OUTPUT/RevFib_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h03fffff0, 'h03ffffff); + $writememh("./OUTPUT/RevFib_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, `INIT_STACK_POINTER - 'h0f, `INIT_STACK_POINTER); /* END : test 2*/ end @@ -94,7 +94,7 @@ begin #5000 $write("\n"); $write("===> Done simulating CS147_SP17_HW01_02.dat\n", ""); $write("\n"); - $writememh("./OUTPUT/CS147_SP17_HW01_02_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h01008000, 'h0100800A); + $writememh("./OUTPUT/CS147_SP17_HW01_02_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h00048000, 'h0004800A); /* END : test 3*/ end @@ -110,7 +110,7 @@ begin #6000 $write("\n"); $write("===> Done simulating CS147_FL15_HW01_02.dat\n", ""); $write("\n"); - $writememh("./OUTPUT/CS147_FL15_HW01_02_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h03fffff6, 'h03ffffff); + $writememh("./OUTPUT/CS147_FL15_HW01_02_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, `INIT_STACK_POINTER - 9, `INIT_STACK_POINTER); /* END : test 4*/ end @@ -126,8 +126,8 @@ begin #5000 $write("\n"); $write("===> Done simulating CS147_SP15_HW01_02.dat\n", ""); $write("\n"); - $writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h01008000, 'h01008005); - $writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h03fffffA, 'h03ffffff); + $writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h00048000, 'h00048005); + $writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, `INIT_STACK_POINTER - 5, `INIT_STACK_POINTER); /* END : test 5*/ end $stop; diff --git a/TESTPROGRAM/CS147_FL15_HW01_02.dat b/TESTPROGRAM/CS147_FL15_HW01_02.dat index 613370c..3028352 100644 --- a/TESTPROGRAM/CS147_FL15_HW01_02.dat +++ b/TESTPROGRAM/CS147_FL15_HW01_02.dat @@ -1,7 +1,7 @@ // ------ Program Part ---- @0001000 2021000A // addi r1, r1, 0xA; -20421008 // addi r2, r2, 0x1008; +20420048 // addi r2, r2, 0x0048; 00401301 // sll r2, r2, 0xC; 00411820 // add r3, r2, r1; 3C848000 // lui r4, r4, 0x8000; @@ -21,25 +21,25 @@ // ------ Data Part ---- -@01008000 -005 // 01008000 -008 // 01008001 -009 // 01008002 -010 // 01008003 -020 // 01008004 -029 // 01008005 -02D // 01008006 -02F // 01008007 -032 // 01008008 -037 // 01008009 -002 // 0100800A -004 // 0100800B -008 // 0100800C -010 // 0100800D -020 // 0100800E -040 // 0100800F -080 // 01008010 -100 // 01008011 -200 // 01008012 -400 // 01008013 +@00048000 +005 // 0004 8000 +008 // 0004 8001 +009 // 0004 8002 +010 // 0004 8003 +020 // 0004 8004 +029 // 0004 8005 +02D // 0004 8006 +02F // 0004 8007 +032 // 0004 8008 +037 // 0004 8009 +002 // 0004 800A +004 // 0004 800B +008 // 0004 800C +010 // 0004 800D +020 // 0004 800E +040 // 0004 800F +080 // 0004 8010 +100 // 0004 8011 +200 // 0004 8012 +400 // 0004 8013 diff --git a/TESTPROGRAM/CS147_SP15_HW01_02.dat b/TESTPROGRAM/CS147_SP15_HW01_02.dat index d30e339..052aeb0 100644 --- a/TESTPROGRAM/CS147_SP15_HW01_02.dat +++ b/TESTPROGRAM/CS147_SP15_HW01_02.dat @@ -2,7 +2,7 @@ 20000001 // addi r0, r0, 0x1; 20210002 // addi r1, r1, 0x2; 20420000 // addi r2, r2, 0x0; -3C630100 // lui r3, 0x100; +3C630004 // lui r3, 0x0004; 34638000 // ori r3, r3, 0x8000; 20840005 // addi r4, r4, 0x5; 00010020 // LOOP: add r0, r0, r1; diff --git a/TESTPROGRAM/CS147_SP17_HW01_02.dat b/TESTPROGRAM/CS147_SP17_HW01_02.dat index 8374977..602d586 100644 --- a/TESTPROGRAM/CS147_SP17_HW01_02.dat +++ b/TESTPROGRAM/CS147_SP17_HW01_02.dat @@ -1,6 +1,6 @@ // ------ Program Part ---- @0001000 -20001008 // addi r0, r0, 0x1008 +20000048 // addi r0, r0, 0x0048 00000301 // sll r0, r0, 0xC 20420009 // addi r2, r2, 0x9 10410007 // LOOP: beq r1, r2, END @@ -14,15 +14,15 @@ AC050000 // sw r5, r0, 0x0 AC050000 // END: sw r5, r0, 0x0 // ------ Data Part ---- -@01008000 -0A // 0100 8000 -0B // 0100 8001 -0C // 0100 8002 -0D // 0100 8003 -0E // 0100 8004 -0F // 0100 8005 -10 // 0100 8006 -11 // 0100 8007 -12 // 0100 8008 -13 // 0100 8008 +@00048000 +0A // 0004 8000 +0B // 0004 8001 +0C // 0004 8002 +0D // 0004 8003 +0E // 0004 8004 +0F // 0004 8005 +10 // 0004 8006 +11 // 0004 8007 +12 // 0004 8008 +13 // 0004 8008 diff --git a/TESTPROGRAM/fibonacci.dat b/TESTPROGRAM/fibonacci.dat index 36cbd46..79a12d4 100644 --- a/TESTPROGRAM/fibonacci.dat +++ b/TESTPROGRAM/fibonacci.dat @@ -1,6 +1,6 @@ @0001000 20420001 // addi r2, r2, 0x0001; -3C000100 // lui r0, 0x0100; +3C000004 // lui r0, 0x0004; AC010000 // sw r1, r0, 0x0000; 20000001 // loop: addi r0, r0, 0x0001; AC020000 // sw r2, r0, 0x0000; diff --git a/prj_definition.v b/prj_definition.v index 540b1c6..eb8cbaa 100644 --- a/prj_definition.v +++ b/prj_definition.v @@ -23,7 +23,7 @@ `define ALU_OPRN_INDEX_LIMIT (`ALU_OPRN_WIDTH -1) `define ADDRESS_WIDTH 26 `define ADDRESS_INDEX_LIMIT (`ADDRESS_WIDTH -1) -`define MEM_SIZE (2 ** `ADDRESS_WIDTH) +`define MEM_SIZE (2 ** (`ADDRESS_WIDTH - 6)) `define MEM_INDEX_LIMIT (`MEM_SIZE - 1) `define NUM_OF_REG 32 `define REG_INDEX_LIMIT (`NUM_OF_REG -1) @@ -41,4 +41,4 @@ // define ISA parameters `define INST_START_ADDR 32'h00001000 -`define INIT_STACK_POINTER 32'h03ffffff +`define INIT_STACK_POINTER 32'h000fffff -- 2.47.2 From b651f04748acdeff63a6a19453c0ea2acc9fd087 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Mon, 18 Nov 2024 00:47:16 -0800 Subject: [PATCH 13/18] control unit: more progress, fibonacci working --- OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat | 12 ++++----- OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat | 2 +- OUTPUT/CS147_SP17_HW01_02_mem_dump.dat | 22 ++++++++--------- OUTPUT/RevFib_mem_dump.dat | 2 +- OUTPUT/fibonacci_mem_dump.dat | 30 +++++++++++------------ control_unit.v | 9 ++++++- 6 files changed, 42 insertions(+), 35 deletions(-) diff --git a/OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat b/OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat index 2bf39c6..7d31300 100644 --- a/OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat +++ b/OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat @@ -1,9 +1,9 @@ // memory data file (do not edit the following line - required for mem load use) // instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 +00000001 +00000004 +00000004 +00000010 +00000010 +00000040 diff --git a/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat b/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat index 2bf39c6..5801f0c 100644 --- a/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat +++ b/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat @@ -6,4 +6,4 @@ 00000000 00000000 00000000 -00000000 +00000200 diff --git a/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat b/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat index 6e829de..2baca37 100644 --- a/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat +++ b/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat @@ -1,14 +1,14 @@ // memory data file (do not edit the following line - required for mem load use) // instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress -0000000a -0000000b -0000000c -0000000d -0000000e -0000000f -00000010 -00000011 -00000012 -00000013 -00000000 +00090001 +00090003 +00090005 +00090007 +00090009 +0009000b +0009000d +0009000f +00090011 +00090013 +00090015 diff --git a/OUTPUT/RevFib_mem_dump.dat b/OUTPUT/RevFib_mem_dump.dat index 78993eb..60d2af6 100644 --- a/OUTPUT/RevFib_mem_dump.dat +++ b/OUTPUT/RevFib_mem_dump.dat @@ -16,4 +16,4 @@ 00000000 00000000 00000000 -00000000 +00000059 diff --git a/OUTPUT/fibonacci_mem_dump.dat b/OUTPUT/fibonacci_mem_dump.dat index 78993eb..8f7ed59 100644 --- a/OUTPUT/fibonacci_mem_dump.dat +++ b/OUTPUT/fibonacci_mem_dump.dat @@ -2,18 +2,18 @@ // instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 +00000001 +00000001 +00000002 +00000003 +00000005 +00000008 +0000000d +00000015 +00000022 +00000037 +00000059 +00000090 +000000e9 +00000179 +00000262 diff --git a/control_unit.v b/control_unit.v index aa9ea8d..d06797c 100644 --- a/control_unit.v +++ b/control_unit.v @@ -171,6 +171,8 @@ endtask reg read, write; buf (READ, read); buf (WRITE, write); +//assign READ = read; +//assign WRITE = write; reg [31:0] C; @@ -313,13 +315,18 @@ always @ (state) begin // wd_sel_3 - pc_inc or wd_sel_2 // jal - pc_inc, else wd_sel_2 C[`wd_sel_3] = opcode == 6'h03 ? 1'b0 : 1'b1; + // ma_sel_1 - alu_out for lw or sw, sp for push or pop + C[`ma_sel_1] = opcode == `OP_LW || opcode == `OP_SW ? 1'b0 : 1'b1; + // ma_sel_2 - 1 for pc, 0 for everything else + C[`ma_sel_2] = opcode == `OP_LW || opcode == `OP_SW || opcode == `OP_PUSH || opcode == `OP_POP ? 1'b0 : 1'b1; // md_sel_1 - r1 for push, r2 for sw C[`md_sel_1] = opcode == 6'h1b ? 1'b1 : 1'b0; end `PROC_MEM: begin // load now // push or sw - write to memory - if (opcode == 6'h1b || opcode == 6'h2b) begin + if (opcode == `OP_PUSH || opcode == `OP_SW) begin + read = 1'b0; write = 1'b1; end -- 2.47.2 From 507fa2e8638cf5c78dc958a70ab11fd002eb8c36 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Mon, 18 Nov 2024 22:18:26 -0800 Subject: [PATCH 14/18] control unit: passing SP15 and SP17 --- OUTPUT/CS147_FL15_HW01_02_mem_dump.dat | 2 +- OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat | 2 +- OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat | 2 +- OUTPUT/CS147_SP17_HW01_02_mem_dump.dat | 22 +-- control_unit.v | 197 +++++++++++----------- data_path.v | 2 +- 6 files changed, 109 insertions(+), 118 deletions(-) diff --git a/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat b/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat index 6b4ebd8..cdecec6 100644 --- a/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat +++ b/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat @@ -10,4 +10,4 @@ 00000000 00000000 00000000 -00000000 +00000020 diff --git a/OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat b/OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat index 7d31300..25e4ab7 100644 --- a/OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat +++ b/OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat @@ -6,4 +6,4 @@ 00000004 00000010 00000010 -00000040 +00000000 diff --git a/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat b/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat index 5801f0c..a7527bd 100644 --- a/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat +++ b/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat @@ -6,4 +6,4 @@ 00000000 00000000 00000000 -00000200 +00000020 diff --git a/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat b/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat index 2baca37..99ec22b 100644 --- a/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat +++ b/OUTPUT/CS147_SP17_HW01_02_mem_dump.dat @@ -1,14 +1,14 @@ // memory data file (do not edit the following line - required for mem load use) // instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress -00090001 -00090003 -00090005 -00090007 -00090009 -0009000b -0009000d -0009000f -00090011 -00090013 -00090015 +00000015 +00000017 +00000019 +0000001b +0000001d +0000001f +00000021 +00000023 +00000025 +00000025 +00000000 diff --git a/control_unit.v b/control_unit.v index d06797c..ff5104d 100644 --- a/control_unit.v +++ b/control_unit.v @@ -107,56 +107,56 @@ input [`DATA_INDEX_LIMIT:0] INSTRUCTION; task print_instruction; input [`DATA_INDEX_LIMIT:0] inst; -reg [5:0] opcode2; -reg [4:0] rs2; -reg [4:0] rt2; -reg [4:0] rd2; -reg [4:0] shamt2; -reg [5:0] funct2; -reg [15:0] immediate2; -reg [25:0] address2; +reg [5:0] opcode; +reg [4:0] rs; +reg [4:0] rt; +reg [4:0] rd; +reg [4:0] shamt; +reg [5:0] funct; +reg [15:0] imm; +reg [25:0] addr; begin // parse the instruction // R-type -{opcode2, rs2, rt2, rd2, shamt2, funct2} = inst; +{opcode, rs, rt, rd, shamt, funct} = inst; // I-type -{opcode2, rs2, rt2, immediate2 } = inst; +{opcode, rs, rt, imm} = inst; // J-type -{opcode2, address2} = inst; +{opcode, addr} = inst; $write("@ %6dns -> [0X%08h] ", $time, inst); -case(opcode2) +case(opcode) // R-Type 6'h00 : begin - case(funct2) - 6'h20: $write("add r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd2, rs2, rt2); - 6'h01: $write("sll r[%02d], r[%02d], %2d;", rd2, rs2, shamt2); - 6'h02: $write("srl r[%02d], 0X%02h, r[%02d];", rd2, rs2, shamt2); - 6'h08: $write("jr r[%02d];", rs2); + case(funct) + 6'h20: $write("add r[%02d], r[%02d], r[%02d];", rd, rs, rt); + 6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd, rs, rt); + 6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd, rs, rt); + 6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd, rs, rt); + 6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd, rs, rt); + 6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd, rs, rt); + 6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd, rs, rt); + 6'h01: $write("sll r[%02d], r[%02d], %2d;", rd, rs, shamt); + 6'h02: $write("srl r[%02d], 0X%02h, r[%02d];", rd, rs, shamt); + 6'h08: $write("jr r[%02d];", rs); default: $write(""); endcase end // I-type - 6'h08 : $write("addi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); - 6'h1d : $write("muli r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); - 6'h0c : $write("andi r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); - 6'h0d : $write("ori r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); - 6'h0f : $write("lui r[%02d], 0X%04h;", rt2, immediate2); - 6'h0a : $write("slti r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); - 6'h04 : $write("beq r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); - 6'h05 : $write("bne r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); - 6'h23 : $write("lw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); - 6'h2b : $write("sw r[%02d], r[%02d], 0X%04h;", rt2, rs2, immediate2); + 6'h08 : $write("addi r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + 6'h1d : $write("muli r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + 6'h0c : $write("andi r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + 6'h0d : $write("ori r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + 6'h0f : $write("lui r[%02d], 0X%04h;", rt, imm); + 6'h0a : $write("slti r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + 6'h04 : $write("beq r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + 6'h05 : $write("bne r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + 6'h23 : $write("lw r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + 6'h2b : $write("sw r[%02d], r[%02d], 0X%04h;", rt, rs, imm); // J-Type - 6'h02 : $write("jmp 0X%07h;", address2); - 6'h03 : $write("jal 0X%07h;", address2); + 6'h02 : $write("jmp 0X%07h;", addr); + 6'h03 : $write("jal 0X%07h;", addr); 6'h1b : $write("push;"); 6'h1c : $write("pop;"); default: $write(""); @@ -228,6 +228,7 @@ always @ (state) begin // decode - parse instruction and read values from register file `PROC_DECODE: begin // loaded in previous state, set to 0 + C[`ma_sel_2] = 1'b0; read = 1'b0; // load now C[`ir_load] = 1'b1; @@ -239,21 +240,22 @@ always @ (state) begin // loaded in previous state, set to 0 C[`ir_load] = 1'b0; // selections - // r1_sel_1: push - store value of r0 at stack pointer - C[`r1_sel_1] = opcode != 6'h1b ? 1'b0 : 1'b1; - // wa_sel_1: R-type - write to rd, I-type - write to rt - C[`wa_sel_1] = opcode == 6'h00 ? 1'b0 : 1'b1; - // wa_sel_2: jal - write to r31, pop - write to r0 - C[`wa_sel_2] = opcode == 6'h03 ? 1'b1 : 1'b0; + // r1_sel_1: rs by default (0), push - r1 (1) + C[`r1_sel_1] = opcode == `OP_PUSH; + // wa_sel_1: R-type - write to rd (0), I-type - write to rt (1) + C[`wa_sel_1] = opcode != `OP_RTYPE; + // wa_sel_2: jal - write to r31 (0), pop - write to r0 (1) + C[`wa_sel_2] = opcode == `OP_POP; // wa_sel_3: push or pop - wa_sel_2, else wa_sel_1 - C[`wa_sel_3] = opcode == 6'h03 || opcode == 6'h1c ? 1'b0 : 1'b1; - // jr - jump to address in register - C[`pc_sel_1] = opcode == 6'h00 && funct == 6'h08 ? 1'b0 : 1'b1; - // beq, bne - branch if equal or not equal + // wa_sel_3: wa_sel_2 if push or pop (0), else wa_sel_1 (1) + C[`wa_sel_3] = ~(opcode == `OP_PUSH || opcode == `OP_POP); + // pc_sel_1: jr - jump to address in rs (0), else pc_inc (1) + C[`pc_sel_1] = ~(opcode == `OP_JMP && funct == `FN_JR); + // pc_sel_2: pc_sel_1 by default (0), beq, bne - branch if equal or not equal (1) // TODO: this should only be selected if the condition is met - // pc_sel_2 = opcode == 6'h04 || opcode == 6'h05 ? 1'b1 : 1'b0; - // jmp, jal - jump to address - C[`pc_sel_3] = opcode == `OP_JMP || opcode == `OP_JAL ? 1'b0 : 1'b1; + // pc_sel_2 = opcode == `OP_BEQ || opcode == `OP_BNE; + // pc_sel_3: jmp or jal - jump to address (0), else pc_sel_2 (1) + C[`pc_sel_3] = ~(opcode == `OP_JMP || opcode == `OP_JAL); // alu_oprn - operation to be performed by ALU // R-type @@ -278,62 +280,52 @@ always @ (state) begin `OP_ADDI: C[`alu_oprn] = `ALU_ADD; // addi `OP_MULI: C[`alu_oprn] = `ALU_MUL; // muli `OP_ANDI: C[`alu_oprn] = `ALU_AND; // andi - `OP_ORI: C[`alu_oprn] = `ALU_OR; // ori + `OP_ORI: C[`alu_oprn] = `ALU_OR; // ori `OP_SLTI: C[`alu_oprn] = `ALU_SLT; // slti - `OP_BEQ: C[`alu_oprn] = `ALU_SUB; // beq - sub - `OP_BNE: C[`alu_oprn] = `ALU_SUB; // bne - sub - `OP_LW: C[`alu_oprn] = `ALU_ADD; // lw - add - `OP_SW: C[`alu_oprn] = `ALU_ADD; // sw - add + `OP_BEQ: C[`alu_oprn] = `ALU_SUB; // beq - sub + `OP_BNE: C[`alu_oprn] = `ALU_SUB; // bne - sub + `OP_LW: C[`alu_oprn] = `ALU_ADD; // lw - add + `OP_SW: C[`alu_oprn] = `ALU_ADD; // sw - add // J-type `OP_PUSH: C[`alu_oprn] = `ALU_SUB; // push - sub - `OP_POP: C[`alu_oprn] = `ALU_ADD; // pop - add - default: C[`alu_oprn] = `ALU_NOP; + `OP_POP: C[`alu_oprn] = `ALU_ADD; // pop - add + default: C[`alu_oprn] = `ALU_NOP; endcase end - // op1_sel_1 - select r1 or sp based on opcode - // push or pop - sp, else r1 - C[`op1_sel_1] = opcode == 6'h1b || opcode == 6'h1c ? 1'b1 : 1'b0; - // op2_sel_1 - select 1 or shamt based on alu_oprn - // sll or srl - shamt, else 1 (for increments/decrements) - C[`op2_sel_1] = C[`alu_oprn] == 6'h04 || C[`alu_oprn] == 6'h05 ? 1'b1 : 1'b0; - // op2_sel_2 - select imm_zx or imm_sx based on alu_oprn - // logical (and, or) - imm_zx, else imm_sx; ('nor' not availble in I-type) - C[`op2_sel_2] = C[`alu_oprn] == 6'h06 || C[`alu_oprn] == 6'h07 ? 1'b0 : 1'b1; - // op2_sel_3 - select op2_sel_2 or op2_sel_1 based on alu_oprn - // R-type - op2_sel_1, I-type - op2_sel_2 - C[`op2_sel_3] = opcode == 6'h00 ? 1'b1 : 1'b0; - // op2_sel_4 - select op2_sel_3 or r2 - // I-type or shift or inc/dec - op2_sel_3, else r2 - // i.e. r2 only if R-type and not shift - C[`op2_sel_4] = opcode != 6'h00 || C[`alu_oprn] == 6'h04 || C[`alu_oprn] == 6'h05 ? 1'b0 : 1'b1; + // op1_sel_1: r1 by default (0), push or pop - sp (1) + C[`op1_sel_1] = opcode == `OP_PUSH || opcode == `OP_POP; + // op2_sel_1: const 1 (for inc/dec) (0), shamnt for sll/srl (1) + C[`op2_sel_1] = opcode == `OP_RTYPE && (funct == `FN_SLL || funct == `FN_SRL); + // op2_sel_2: imm_zx for logical and/or (0), imm_sx otherise (1) + // ('nor' not availble in I-type) + C[`op2_sel_2] = ~(opcode == `OP_ANDI || opcode == `OP_ORI); + // op2_sel_3: op2_sel_2 for I-type (0), op2_sel_1 for R-type shift (1) + C[`op2_sel_3] = opcode == `OP_RTYPE; + // op2_sel_4: op2_sel_3 for I-type (except beq, bne) or R-type shift or inc/dec (0), else r2 (1) + // i.e. r2 if R-type (except sll/srl), or bne/beq + C[`op2_sel_4] = opcode == `OP_RTYPE && ~(funct == `FN_SLL || funct == `FN_SRL) + || opcode == `OP_BEQ || opcode == `OP_BNE; - // wd_sel_1 - alu_out or DATA_IN - C[`wd_sel_1] = 1'b0; - // wd_sel_2 - wd_sel_1 or imm_zx_lsb - // lui - imm_zx_lsb, else wd_sel_1 - C[`wd_sel_2] = opcode == 6'h0f ? 1'b1 : 1'b0; - // wd_sel_3 - pc_inc or wd_sel_2 - // jal - pc_inc, else wd_sel_2 - C[`wd_sel_3] = opcode == 6'h03 ? 1'b0 : 1'b1; - // ma_sel_1 - alu_out for lw or sw, sp for push or pop - C[`ma_sel_1] = opcode == `OP_LW || opcode == `OP_SW ? 1'b0 : 1'b1; - // ma_sel_2 - 1 for pc, 0 for everything else - C[`ma_sel_2] = opcode == `OP_LW || opcode == `OP_SW || opcode == `OP_PUSH || opcode == `OP_POP ? 1'b0 : 1'b1; - // md_sel_1 - r1 for push, r2 for sw - C[`md_sel_1] = opcode == 6'h1b ? 1'b1 : 1'b0; + // wd_sel_1: alu_out or DATA_IN + // wd_sel_1: alu_out by default (0), DATA_IN for lw or pop (1) + C[`wd_sel_1] = opcode == `OP_LW || opcode == `OP_POP; + // wd_sel_2: wd_sel_1 by default (0), imm_zx_lsb for lui (1) + C[`wd_sel_2] = opcode == `OP_LUI; + // wd_sel_3: pc_inc for jal (0), else wd_sel_2 (1) + C[`wd_sel_3] = ~(opcode == `OP_JAL); + // ma_sel_1: alu_out for lw or sw, sp for push or pop + // ma_sel_1: alu_out for lw or sw (0), sp for push or pop (1) + C[`ma_sel_1] = opcode == `OP_PUSH || opcode == `OP_POP; + // ma_sel_2: 0 for every memory access instruction (lw, sw, push, pop), 1 for fetch + C[`ma_sel_2] = 1'b0; + // md_sel_1: r2 for sw (0), r1 for push (1) + C[`md_sel_1] = opcode == `OP_PUSH; end `PROC_MEM: begin - // load now // push or sw - write to memory - if (opcode == `OP_PUSH || opcode == `OP_SW) begin - - read = 1'b0; - write = 1'b1; - end - else begin -// read = 1'b1; -// write = 1'b0; - end + write = opcode == `OP_PUSH || opcode == `OP_SW; + // pop or lw - read from memory + read = opcode == `OP_POP || opcode == `OP_LW; end `PROC_WB: begin // loaded in previous state, set to 0 @@ -343,15 +335,14 @@ always @ (state) begin C[`pc_load] = 1'b1; // write to register file if // R-type (except jr) or I-type (except beq, bne, sw) or pop or jal - C[`reg_w] = (opcode == 6'h00 && funct != 6'h08) // R-type (except jr) - || (opcode == 6'h08 || opcode == 6'h1d || opcode == 6'h0c || opcode == 6'h0d - || opcode == 6'h0f || opcode == 6'h0a || opcode == 6'h23) // I-type (except beq, bne, sw) - || (opcode == 6'h1c || opcode == 6'h03) // pop or jal - ? 1'b1 : 1'b0; + C[`reg_w] = (opcode == `OP_RTYPE && funct != `FN_JR) // R-type (except jr) + || (opcode == `OP_ADDI || opcode == `OP_MULI || opcode == `OP_ANDI || opcode == `OP_ORI + || opcode == `OP_LUI || opcode == `OP_SLTI || opcode == `OP_LW) // I-type (except beq, bne, sw) + || (opcode == `OP_POP || opcode == `OP_JAL) // pop or jal + ; // selections - // pc_sel_2 - branch if equal or not equal - C[`pc_sel_2] = (opcode == 6'h04 && ZERO) || (opcode == 6'h05 && ~ZERO) ? 1'b1 : 1'b0; - + // pc_sel_2: branch if equal or not equal + C[`pc_sel_2] = ((opcode == `OP_BEQ) && ZERO) || ((opcode == `OP_BNE) && ~ZERO); end endcase end diff --git a/data_path.v b/data_path.v index 4ec4653..d87e513 100644 --- a/data_path.v +++ b/data_path.v @@ -152,7 +152,7 @@ wire [31:0] pc_sel; wire [31:0] pc_branch, pc_jump, pc_sel_p1, pc_sel_p2; RC_ADD_SUB_32 pc_inc_inst(.Y(pc_inc), .CO(), .A(pc), .B(32'b1), .SnA(1'b0)); MUX32_2x1 mux_pc_sel_p1(pc_sel_p1, r1, pc_inc, pc_sel_1); -RC_ADD_SUB_32 pc_sel_2_inst(.Y(pc_branch), .CO(), .A(pc), .B(imm_sx), .SnA(1'b0)); +RC_ADD_SUB_32 pc_sel_2_inst(.Y(pc_branch), .CO(), .A(pc_inc), .B(imm_sx), .SnA(1'b0)); MUX32_2x1 mux_pc_sel_p2(pc_sel_p2, pc_sel_p1, pc_branch, pc_sel_2); buf pc_jump_buf [31:0] (pc_jump, {6'b0, addr}); MUX32_2x1 mux_pc_sel(pc_sel, pc_jump, pc_sel_p2, pc_sel_3); -- 2.47.2 From 0198e8be41b880d3d6d9df386db21644c9ba03a0 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Mon, 18 Nov 2024 23:00:06 -0800 Subject: [PATCH 15/18] control unit: fix stack pointer inc/dec, passing SP15, FL15, RevFib --- OUTPUT/CS147_FL15_HW01_02_mem_dump.dat | 18 +++++++------- OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat | 8 +++--- OUTPUT/RevFib_mem_dump.dat | 30 +++++++++++------------ control_unit.v | 13 +++++++--- 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat b/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat index cdecec6..f6f6496 100644 --- a/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat +++ b/OUTPUT/CS147_FL15_HW01_02_mem_dump.dat @@ -1,13 +1,13 @@ // memory data file (do not edit the following line - required for mem load use) // instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 00000020 +00000020 +00000010 +00000010 +00000009 +00000008 +00000008 +00000005 +00000004 +00000002 diff --git a/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat b/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat index a7527bd..62a9cae 100644 --- a/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat +++ b/OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat @@ -2,8 +2,8 @@ // instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 00000000 -00000000 -00000000 -00000000 -00000000 00000020 +00000008 +00000008 +00000002 +00000002 diff --git a/OUTPUT/RevFib_mem_dump.dat b/OUTPUT/RevFib_mem_dump.dat index 60d2af6..23be7b1 100644 --- a/OUTPUT/RevFib_mem_dump.dat +++ b/OUTPUT/RevFib_mem_dump.dat @@ -1,19 +1,19 @@ // memory data file (do not edit the following line - required for mem load use) // instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +ffffffc9 +00000022 +ffffffeb +0000000d +fffffff8 +00000005 +fffffffd +00000002 +ffffffff +00000001 00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000059 +00000001 +00000001 +00000002 +00000003 +00000005 diff --git a/control_unit.v b/control_unit.v index ff5104d..a794b75 100644 --- a/control_unit.v +++ b/control_unit.v @@ -239,6 +239,8 @@ always @ (state) begin print_instruction(INSTRUCTION); // loaded in previous state, set to 0 C[`ir_load] = 1'b0; + // load now + C[`sp_load] = opcode == `OP_POP; // sp is decremented before pop // selections // r1_sel_1: rs by default (0), push - r1 (1) C[`r1_sel_1] = opcode == `OP_PUSH; @@ -294,13 +296,14 @@ always @ (state) begin end // op1_sel_1: r1 by default (0), push or pop - sp (1) C[`op1_sel_1] = opcode == `OP_PUSH || opcode == `OP_POP; - // op2_sel_1: const 1 (for inc/dec) (0), shamnt for sll/srl (1) + // op2_sel_1: const 1 (for inc/dec) (0), shamt for sll/srl (1) C[`op2_sel_1] = opcode == `OP_RTYPE && (funct == `FN_SLL || funct == `FN_SRL); // op2_sel_2: imm_zx for logical and/or (0), imm_sx otherise (1) // ('nor' not availble in I-type) C[`op2_sel_2] = ~(opcode == `OP_ANDI || opcode == `OP_ORI); - // op2_sel_3: op2_sel_2 for I-type (0), op2_sel_1 for R-type shift (1) - C[`op2_sel_3] = opcode == `OP_RTYPE; + // op2_sel_3: op2_sel_2 for I-type (0), op2_sel_1 for R-type shift or inc/dec (1) + // inc/dec is push or pop + C[`op2_sel_3] = opcode == `OP_RTYPE || opcode == `OP_PUSH || opcode == `OP_POP; // op2_sel_4: op2_sel_3 for I-type (except beq, bne) or R-type shift or inc/dec (0), else r2 (1) // i.e. r2 if R-type (except sll/srl), or bne/beq C[`op2_sel_4] = opcode == `OP_RTYPE && ~(funct == `FN_SLL || funct == `FN_SRL) @@ -322,12 +325,16 @@ always @ (state) begin C[`md_sel_1] = opcode == `OP_PUSH; end `PROC_MEM: begin + // loaded in previous state, set to 0 + C[`sp_load] = 1'b0; // push or sw - write to memory write = opcode == `OP_PUSH || opcode == `OP_SW; // pop or lw - read from memory read = opcode == `OP_POP || opcode == `OP_LW; end `PROC_WB: begin + // load now + C[`sp_load] = opcode == `OP_PUSH; // sp is incremented after push // loaded in previous state, set to 0 read = 1'b0; write = 1'b0; -- 2.47.2 From ceba9d6fd5d61112aa75796cd0a8e4ca506b5c03 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Wed, 20 Nov 2024 00:52:11 -0800 Subject: [PATCH 16/18] control unit: fix jal, add comprehensive instruction test --- OUTPUT/all_test_mem_dump_01.dat | 21 ++++++++++++++ OUTPUT/all_test_mem_dump_02.dat | 9 ++++++ TESTBENCH/da_vinci_tb.v | 20 +++++++++++++- TESTPROGRAM/all_test.dat | 49 +++++++++++++++++++++++++++++++++ control_unit.v | 10 +++---- 5 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 OUTPUT/all_test_mem_dump_01.dat create mode 100644 OUTPUT/all_test_mem_dump_02.dat create mode 100644 TESTPROGRAM/all_test.dat diff --git a/OUTPUT/all_test_mem_dump_01.dat b/OUTPUT/all_test_mem_dump_01.dat new file mode 100644 index 0000000..20b6c36 --- /dev/null +++ b/OUTPUT/all_test_mem_dump_01.dat @@ -0,0 +1,21 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00001337 +000039a5 +00002024 +0000335b +fffff313 +00000ced +026993bc +00000024 +00003337 +ffffccc8 +00000001 +00000000 +00013370 +00000133 +000039a5 +00000005 +00000005 +fffff313 diff --git a/OUTPUT/all_test_mem_dump_02.dat b/OUTPUT/all_test_mem_dump_02.dat new file mode 100644 index 0000000..d823fc2 --- /dev/null +++ b/OUTPUT/all_test_mem_dump_02.dat @@ -0,0 +1,9 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DA_VINCI_TB/da_vinci_inst/memory_inst/memory_inst/sram_32x64m +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000000 +00000000 +00000000 +00001337 diff --git a/TESTBENCH/da_vinci_tb.v b/TESTBENCH/da_vinci_tb.v index 9e8cde2..17f8f2a 100644 --- a/TESTBENCH/da_vinci_tb.v +++ b/TESTBENCH/da_vinci_tb.v @@ -30,7 +30,8 @@ wire [`DATA_INDEX_LIMIT:0] MEM_DATA_OUT, MEM_DATA_IN; // reset reg RST; -integer t1=1, t2=1, t3=1, t4=1, t5=1; +//integer t1=1, t2=1, t3=1, t4=1, t5=1, t6=1; +integer t1=0, t2=0, t3=0, t4=0, t5=0, t6=1; // Clock generator instance CLK_GENERATOR clk_gen_inst(.CLK(CLK)); @@ -129,6 +130,23 @@ begin $writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h00048000, 'h00048005); $writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, `INIT_STACK_POINTER - 5, `INIT_STACK_POINTER); /* END : test 5*/ +end + +if (t6 === 1) +begin +/* START : test 6*/ +#5 RST=1'b0; +#5 RST=1'b1; + $write("\n"); + $write("===> Simulating all_test.dat\n", ""); + $write("\n"); + $readmemh("./TESTPROGRAM/all_test.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m); +#5000 $write("\n"); + $write("===> Done simulating all_test.dat\n", ""); + $write("\n"); + $writememh("./OUTPUT/all_test_mem_dump_01.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h00048000, 'h00048011); + $writememh("./OUTPUT/all_test_mem_dump_02.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, `INIT_STACK_POINTER - 5, `INIT_STACK_POINTER); +/* END : test 6*/ end $stop; diff --git a/TESTPROGRAM/all_test.dat b/TESTPROGRAM/all_test.dat new file mode 100644 index 0000000..7493e86 --- /dev/null +++ b/TESTPROGRAM/all_test.dat @@ -0,0 +1,49 @@ +@0001000 +20001337 // addi r0, r0, 0x1337 +6c000000 // push +3c1e0004 // lui r30, 0x0004 +37de8000 // ori r30, r30 0x00008000 +afc00000 // sw r0, r30, 0x0 +0c001014 // jal 0x00001014 +70000000 // pop +20212024 // addi r1, r1, 0x2024 +00011020 // add r2, r0, r1 +00011822 // sub r3, r0, r1 +00202022 // sub r4, r1, r0 +0001282c // mul r5, r0, r1 +00013024 // and r6, r0, r1 +00013825 // or r7, r0, r1 +00014027 // nor r8, r0, r1 +0001482a // slt r9, r0, r1 +0020502a // slt r10, r1, r0 +00005901 // sll r11, r0, 4 +00006102 // srl r12, r0, 4 +08001017 // jmp 0x00001017 +74000003 // muli r0, r0, 3 +afc00001 // sw r0, r30, 0x1 +03e00008 // jr r31 +8fcd0001 // lw r13, r30, 0x1 +29ae1338 // slti r14, r13, 0x1338 +302f0000 // andi r15, r1, 0x0 +21ef0005 // addi r15, r15, 0x5 +11ee0002 // beq r14, r15, 0x2 +21ce0001 // addi r14, r14, 0x1 +0800101b // jmp 0x0000101b +afc10002 // sw r1, r30, 0x2 +afc20003 // sw r2, r30, 0x3 +afc30004 // sw r3, r30, 0x4 +afc40005 // sw r4, r30, 0x5 +afc50006 // sw r5, r30, 0x6 +afc60007 // sw r6, r30, 0x7 +afc70008 // sw r7, r30, 0x8 +afc80009 // sw r8, r30, 0x9 +afc9000a // sw r9, r30, 0x0a +afca000b // sw r10, r30, 0x0b +afcb000c // sw r11, r30, 0x0c +afcc000d // sw r12, r30, 0x0d +afcd000e // sw r13, r30, 0x0e +afce000f // sw r14, r30, 0x0f +afcf0010 // sw r15, r30, 0x10 +2210fbb1 // addi r16, r16, 0xfbb1 +1470fffe // bne r16, r3, 0xfffe +afd00011 // sw r16, r30, 0x11 diff --git a/control_unit.v b/control_unit.v index a794b75..46fc853 100644 --- a/control_unit.v +++ b/control_unit.v @@ -246,13 +246,13 @@ always @ (state) begin C[`r1_sel_1] = opcode == `OP_PUSH; // wa_sel_1: R-type - write to rd (0), I-type - write to rt (1) C[`wa_sel_1] = opcode != `OP_RTYPE; - // wa_sel_2: jal - write to r31 (0), pop - write to r0 (1) - C[`wa_sel_2] = opcode == `OP_POP; + // wa_sel_2: pop - write to r0 (0), jal - write to r31 (1) + C[`wa_sel_2] = opcode == `OP_JAL; // wa_sel_3: push or pop - wa_sel_2, else wa_sel_1 - // wa_sel_3: wa_sel_2 if push or pop (0), else wa_sel_1 (1) - C[`wa_sel_3] = ~(opcode == `OP_PUSH || opcode == `OP_POP); + // wa_sel_3: wa_sel_2 if push or pop or jal (0), else wa_sel_1 (1) + C[`wa_sel_3] = ~(opcode == `OP_PUSH || opcode == `OP_POP || opcode == `OP_JAL); // pc_sel_1: jr - jump to address in rs (0), else pc_inc (1) - C[`pc_sel_1] = ~(opcode == `OP_JMP && funct == `FN_JR); + C[`pc_sel_1] = ~(opcode == `OP_RTYPE && funct == `FN_JR); // pc_sel_2: pc_sel_1 by default (0), beq, bne - branch if equal or not equal (1) // TODO: this should only be selected if the condition is met // pc_sel_2 = opcode == `OP_BEQ || opcode == `OP_BNE; -- 2.47.2 From 0361dcc1619fd26f1196a7eb182e09e29f72d86b Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Wed, 20 Nov 2024 01:30:47 -0800 Subject: [PATCH 17/18] project: some cleanup --- control_unit.v | 36 ++++++----------- data_path.v | 103 ++++++++++++++----------------------------------- 2 files changed, 40 insertions(+), 99 deletions(-) diff --git a/control_unit.v b/control_unit.v index 46fc853..13f7ec8 100644 --- a/control_unit.v +++ b/control_unit.v @@ -192,7 +192,7 @@ reg [25:0] addr; wire [2:0] state; PROC_SM proc_sm(state, CLK, RST); -// TBD - take action on each +ve edge of clock +// take action on each +ve edge of clock always @ (state) begin // R-type {opcode, rs, rt, rd, shamt, funct} = INSTRUCTION; @@ -201,19 +201,6 @@ always @ (state) begin // J-type {opcode, addr} = INSTRUCTION; - // Print current state -// $write("@ %6dns -> ", $time); -// $write("STATE ", state, ": "); -// case (state) -// `PROC_FETCH: $write("FETCH"); -// `PROC_DECODE: $write("DECODE"); -// `PROC_EXE: $write("EXECUTE"); -// `PROC_MEM: $write("MEMORY"); -// `PROC_WB: $write("WRITE BACK"); -// default: $write("INVALID"); -// endcase -// $write("\n"); - case (state) // fetch - next instruction from memory at PC `PROC_FETCH: begin @@ -222,8 +209,8 @@ always @ (state) begin // memory read = 1'b1; write = 1'b0; - // selections - C[`ma_sel_2] = 1'b1; // load data from mem[PC] + // load data from mem[PC] + C[`ma_sel_2] = 1'b1; end // decode - parse instruction and read values from register file `PROC_DECODE: begin @@ -241,21 +228,21 @@ always @ (state) begin C[`ir_load] = 1'b0; // load now C[`sp_load] = opcode == `OP_POP; // sp is decremented before pop - // selections + // r1_sel_1: rs by default (0), push - r1 (1) C[`r1_sel_1] = opcode == `OP_PUSH; + // wa_sel_1: R-type - write to rd (0), I-type - write to rt (1) C[`wa_sel_1] = opcode != `OP_RTYPE; // wa_sel_2: pop - write to r0 (0), jal - write to r31 (1) C[`wa_sel_2] = opcode == `OP_JAL; - // wa_sel_3: push or pop - wa_sel_2, else wa_sel_1 // wa_sel_3: wa_sel_2 if push or pop or jal (0), else wa_sel_1 (1) C[`wa_sel_3] = ~(opcode == `OP_PUSH || opcode == `OP_POP || opcode == `OP_JAL); + // pc_sel_1: jr - jump to address in rs (0), else pc_inc (1) C[`pc_sel_1] = ~(opcode == `OP_RTYPE && funct == `FN_JR); // pc_sel_2: pc_sel_1 by default (0), beq, bne - branch if equal or not equal (1) - // TODO: this should only be selected if the condition is met - // pc_sel_2 = opcode == `OP_BEQ || opcode == `OP_BNE; + // pc_sel_2 is set after EXE because it depends on ZERO // pc_sel_3: jmp or jal - jump to address (0), else pc_sel_2 (1) C[`pc_sel_3] = ~(opcode == `OP_JMP || opcode == `OP_JAL); @@ -296,31 +283,32 @@ always @ (state) begin end // op1_sel_1: r1 by default (0), push or pop - sp (1) C[`op1_sel_1] = opcode == `OP_PUSH || opcode == `OP_POP; + // op2_sel_1: const 1 (for inc/dec) (0), shamt for sll/srl (1) C[`op2_sel_1] = opcode == `OP_RTYPE && (funct == `FN_SLL || funct == `FN_SRL); // op2_sel_2: imm_zx for logical and/or (0), imm_sx otherise (1) // ('nor' not availble in I-type) C[`op2_sel_2] = ~(opcode == `OP_ANDI || opcode == `OP_ORI); // op2_sel_3: op2_sel_2 for I-type (0), op2_sel_1 for R-type shift or inc/dec (1) - // inc/dec is push or pop + // (inc/dec is for sp with push or pop) C[`op2_sel_3] = opcode == `OP_RTYPE || opcode == `OP_PUSH || opcode == `OP_POP; // op2_sel_4: op2_sel_3 for I-type (except beq, bne) or R-type shift or inc/dec (0), else r2 (1) // i.e. r2 if R-type (except sll/srl), or bne/beq C[`op2_sel_4] = opcode == `OP_RTYPE && ~(funct == `FN_SLL || funct == `FN_SRL) || opcode == `OP_BEQ || opcode == `OP_BNE; - // wd_sel_1: alu_out or DATA_IN // wd_sel_1: alu_out by default (0), DATA_IN for lw or pop (1) C[`wd_sel_1] = opcode == `OP_LW || opcode == `OP_POP; // wd_sel_2: wd_sel_1 by default (0), imm_zx_lsb for lui (1) C[`wd_sel_2] = opcode == `OP_LUI; // wd_sel_3: pc_inc for jal (0), else wd_sel_2 (1) C[`wd_sel_3] = ~(opcode == `OP_JAL); - // ma_sel_1: alu_out for lw or sw, sp for push or pop + // ma_sel_1: alu_out for lw or sw (0), sp for push or pop (1) C[`ma_sel_1] = opcode == `OP_PUSH || opcode == `OP_POP; // ma_sel_2: 0 for every memory access instruction (lw, sw, push, pop), 1 for fetch C[`ma_sel_2] = 1'b0; + // md_sel_1: r2 for sw (0), r1 for push (1) C[`md_sel_1] = opcode == `OP_PUSH; end @@ -387,7 +375,7 @@ always @ (negedge RST) begin state_sel = 3'bxxx; end -// TBD - take action on each +ve edge of clock +// take action on each +ve edge of clock always @ (posedge CLK) begin case (state_sel) `PROC_FETCH: state_sel = `PROC_DECODE; diff --git a/data_path.v b/data_path.v index d87e513..2c68298 100644 --- a/data_path.v +++ b/data_path.v @@ -17,6 +17,7 @@ //------------------------------------------------------------------------------------------ // `include "prj_definition.v" +`include "control_unit.v" // for control signal index macros module DATA_PATH(DATA_OUT, ADDR, ZERO, INSTRUCTION, DATA_IN, CTRL, CLK, RST); // output list @@ -29,53 +30,6 @@ input [`CTRL_WIDTH_INDEX_LIMIT:0] CTRL; input CLK, RST; input [`DATA_INDEX_LIMIT:0] DATA_IN; -wire pc_load, pc_sel_1, pc_sel_2, pc_sel_3, - ir_load, reg_r, reg_w, - r1_sel_1, wa_sel_1, wa_sel_2, wa_sel_3, - - sp_load, op1_sel_1, - op2_sel_1, op2_sel_2, op2_sel_3, op2_sel_4, - - wd_sel_1, wd_sel_2, wd_sel_3, - ma_sel_1, ma_sel_2, - md_sel_1; - -wire [5:0] alu_oprn; - -buf (pc_load, CTRL[0]); -buf (pc_sel_1, CTRL[1]); -buf (pc_sel_2, CTRL[2]); -buf (pc_sel_3, CTRL[3]); - -buf (ir_load, CTRL[4]); - -buf (r1_sel_1, CTRL[5]); -buf (reg_r, CTRL[6]); -buf (reg_w, CTRL[7]); - -buf (sp_load, CTRL[8]); - -buf (op1_sel_1, CTRL[9]); -buf (op2_sel_1, CTRL[10]); -buf (op2_sel_2, CTRL[11]); -buf (op2_sel_3, CTRL[12]); -buf (op2_sel_4, CTRL[13]); - -buf alu_oprn_buf [5:0] (alu_oprn, CTRL[19:14]); - -buf (ma_sel_1, CTRL[20]); -buf (ma_sel_2, CTRL[21]); - -buf (md_sel_1, CTRL[22]); - -buf (wd_sel_1, CTRL[23]); -buf (wd_sel_2, CTRL[24]); -buf (wd_sel_3, CTRL[25]); - -buf (wa_sel_1, CTRL[26]); -buf (wa_sel_2, CTRL[27]); -buf (wa_sel_3, CTRL[28]); - // variables wire [31:0] ir; // Instruction Register wire [31:0] r1, r2; // Register File @@ -83,7 +37,7 @@ wire [31:0] pc, pc_inc; // Program Counter wire [31:0] sp; // Stack Pointer wire [31:0] alu_out; // ALU output -// TODO: Why? +// instruction sent to control unit buf ir_buf [31:0] (INSTRUCTION, ir); // Parse the instruction data @@ -110,27 +64,26 @@ buf imm_buf [15:0] (imm, ir[15:0]); // for J-type buf addr_buf [25:0] (addr, ir[25:0]); - -// Instruction Register input // Instruction Register -D_LATCH32 ir_inst(.Q(ir), .D(DATA_IN), .LOAD(ir_load), .RESET(RST)); +D_LATCH32 ir_inst(.Q(ir), .D(DATA_IN), .LOAD(CTRL[`ir_load]), .RESET(RST)); // Register File Input wire [31:0] r1_sel, wa_sel, wd_sel; wire [31:0] wa_sel_p1, wa_sel_p2, wd_sel_p1, wd_sel_p2; wire [31:0] imm_zx_lsb; buf imm_zx_lsb_buf [31:0] (imm_zx_lsb, {imm, 16'b0}); -MUX32_2x1 mux_r1_sel(r1_sel, {27'b0,rs}, 32'b0, r1_sel_1); -MUX32_2x1 mux_wa_sel_p1(wa_sel_p1, {27'b0,rd}, {27'b0,rt}, wa_sel_1); -// TODO: Why 31? -MUX32_2x1 mux_wa_sel_p2(wa_sel_p2, 32'b0, 31, wa_sel_2); -MUX32_2x1 mux_wa_sel(wa_sel, wa_sel_p2, wa_sel_p1, wa_sel_3); -MUX32_2x1 mux_wd_sel_p1(wd_sel_p1, alu_out,DATA_IN, wd_sel_1); -MUX32_2x1 mux_wd_sel_p2(wd_sel_p2, wd_sel_p1, imm_zx_lsb, wd_sel_2); -MUX32_2x1 mux_wd_sel(wd_sel, pc_inc, wd_sel_p2, wd_sel_3); +MUX32_2x1 mux_r1_sel(r1_sel, {27'b0,rs}, 32'b0, CTRL[`r1_sel_1]); +MUX32_2x1 mux_wa_sel_p1(wa_sel_p1, {27'b0,rd}, {27'b0,rt}, CTRL[`wa_sel_1]); +// 0 for push/pop, 31 for jal +MUX32_2x1 mux_wa_sel_p2(wa_sel_p2, 32'b0, 31, CTRL[`wa_sel_2]); +MUX32_2x1 mux_wa_sel(wa_sel, wa_sel_p2, wa_sel_p1, CTRL[`wa_sel_3]); +MUX32_2x1 mux_wd_sel_p1(wd_sel_p1, alu_out,DATA_IN, CTRL[`wd_sel_1]); +MUX32_2x1 mux_wd_sel_p2(wd_sel_p2, wd_sel_p1, imm_zx_lsb, CTRL[`wd_sel_2]); +MUX32_2x1 mux_wd_sel(wd_sel, pc_inc, wd_sel_p2, CTRL[`wd_sel_3]); // Register File REGISTER_FILE_32x32 rf_inst(.DATA_R1(r1), .DATA_R2(r2), .ADDR_R1(r1_sel[4:0]), .ADDR_R2(rt), - .DATA_W(wd_sel), .ADDR_W(wa_sel[4:0]), .READ(reg_r), .WRITE(reg_w), .CLK(CLK), .RST(RST)); + .DATA_W(wd_sel), .ADDR_W(wa_sel[4:0]), .READ(CTRL[`reg_r]), .WRITE(CTRL[`reg_w]), + .CLK(CLK), .RST(RST)); // ALU Input wire [31:0] op1_sel, op2_sel; @@ -139,40 +92,40 @@ wire [31:0] shamt_zx, imm_sx, imm_zx; buf shamt_zx_buf [31:0] (shamt_zx, {27'b0, shamt}); buf imm_sx_buf [31:0] (imm_sx, {{16{imm[15]}}, imm}); buf imm_zx_buf [31:0] (imm_zx, {16'b0, imm}); -MUX32_2x1 mux_op1_sel(op1_sel, r1, sp, op1_sel_1); -MUX32_2x1 mux_op2_sel_p1(op2_sel_p1, 32'b1, shamt_zx, op2_sel_1); -MUX32_2x1 mux_op2_sel_p2(op2_sel_p2, imm_zx, imm_sx, op2_sel_2); -MUX32_2x1 mux_op2_sel_p3(op2_sel_p3, op2_sel_p2, op2_sel_p1, op2_sel_3); -MUX32_2x1 mux_op2_sel(op2_sel, op2_sel_p3, r2, op2_sel_4); +MUX32_2x1 mux_op1_sel(op1_sel, r1, sp, CTRL[`op1_sel_1]); +MUX32_2x1 mux_op2_sel_p1(op2_sel_p1, 32'b1, shamt_zx, CTRL[`op2_sel_1]); +MUX32_2x1 mux_op2_sel_p2(op2_sel_p2, imm_zx, imm_sx, CTRL[`op2_sel_2]); +MUX32_2x1 mux_op2_sel_p3(op2_sel_p3, op2_sel_p2, op2_sel_p1, CTRL[`op2_sel_3]); +MUX32_2x1 mux_op2_sel(op2_sel, op2_sel_p3, r2, CTRL[`op2_sel_4]); // ALU -ALU alu_inst(.OUT(alu_out), .ZERO(ZERO), .OP1(op1_sel), .OP2(op2_sel), .OPRN(alu_oprn)); +ALU alu_inst(.OUT(alu_out), .ZERO(ZERO), .OP1(op1_sel), .OP2(op2_sel), .OPRN(CTRL[`alu_oprn])); // Progam Counter Input wire [31:0] pc_sel; wire [31:0] pc_branch, pc_jump, pc_sel_p1, pc_sel_p2; RC_ADD_SUB_32 pc_inc_inst(.Y(pc_inc), .CO(), .A(pc), .B(32'b1), .SnA(1'b0)); -MUX32_2x1 mux_pc_sel_p1(pc_sel_p1, r1, pc_inc, pc_sel_1); +MUX32_2x1 mux_pc_sel_p1(pc_sel_p1, r1, pc_inc, CTRL[`pc_sel_1]); RC_ADD_SUB_32 pc_sel_2_inst(.Y(pc_branch), .CO(), .A(pc_inc), .B(imm_sx), .SnA(1'b0)); -MUX32_2x1 mux_pc_sel_p2(pc_sel_p2, pc_sel_p1, pc_branch, pc_sel_2); +MUX32_2x1 mux_pc_sel_p2(pc_sel_p2, pc_sel_p1, pc_branch, CTRL[`pc_sel_2]); buf pc_jump_buf [31:0] (pc_jump, {6'b0, addr}); -MUX32_2x1 mux_pc_sel(pc_sel, pc_jump, pc_sel_p2, pc_sel_3); +MUX32_2x1 mux_pc_sel(pc_sel, pc_jump, pc_sel_p2, CTRL[`pc_sel_3]); // Program Counter defparam pc_inst.PATTERN = `INST_START_ADDR; -REG32_PP pc_inst(.Q(pc), .D(pc_sel), .LOAD(pc_load), .CLK(CLK), .RESET(RST)); +REG32_PP pc_inst(.Q(pc), .D(pc_sel), .LOAD(CTRL[`pc_load]), .CLK(CLK), .RESET(RST)); // Stack Pointer defparam sp_inst.PATTERN = `INIT_STACK_POINTER; -REG32_PP sp_inst(.Q(sp), .D(alu_out), .LOAD(sp_load), .CLK(CLK), .RESET(RST)); +REG32_PP sp_inst(.Q(sp), .D(alu_out), .LOAD(CTRL[`sp_load]), .CLK(CLK), .RESET(RST)); // Data out -MUX32_2x1 mux_data_out(DATA_OUT, r2, r1, md_sel_1); +MUX32_2x1 mux_data_out(DATA_OUT, r2, r1, CTRL[`md_sel_1]); // Address out wire [31:0] ma_sel_p1; -MUX32_2x1 mux_ma_sel_p1(ma_sel_p1, alu_out, sp, ma_sel_1); -// TODO: Check address calculation since it's 26 bit +MUX32_2x1 mux_ma_sel_p1(ma_sel_p1, alu_out, sp, CTRL[`ma_sel_1]); +// discard the upper 6 bits of the address since it's only 26 bit addressable (* keep="soft" *) wire [5:0] _addr_ignored; -MUX32_2x1 mux_ma_sel({_addr_ignored,ADDR}, ma_sel_p1, pc, ma_sel_2); +MUX32_2x1 mux_ma_sel({_addr_ignored,ADDR}, ma_sel_p1, pc, CTRL[`ma_sel_2]); endmodule -- 2.47.2 From a7870b87eb863db0c4351a8e5c2521289aaea769 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Sat, 23 Nov 2024 22:22:12 -0800 Subject: [PATCH 18/18] project: more cleanup --- TESTBENCH/da_vinci_tb.v | 4 +- control_unit.v | 123 +++++++++++++++++++--------------------- 2 files changed, 59 insertions(+), 68 deletions(-) diff --git a/TESTBENCH/da_vinci_tb.v b/TESTBENCH/da_vinci_tb.v index 17f8f2a..c89405f 100644 --- a/TESTBENCH/da_vinci_tb.v +++ b/TESTBENCH/da_vinci_tb.v @@ -30,8 +30,8 @@ wire [`DATA_INDEX_LIMIT:0] MEM_DATA_OUT, MEM_DATA_IN; // reset reg RST; -//integer t1=1, t2=1, t3=1, t4=1, t5=1, t6=1; -integer t1=0, t2=0, t3=0, t4=0, t5=0, t6=1; +integer t1=1, t2=1, t3=1, t4=1, t5=1, t6=1; +//integer t1=0, t2=0, t3=0, t4=0, t5=0, t6=1; // Clock generator instance CLK_GENERATOR clk_gen_inst(.CLK(CLK)); diff --git a/control_unit.v b/control_unit.v index 13f7ec8..40fd783 100644 --- a/control_unit.v +++ b/control_unit.v @@ -19,7 +19,7 @@ //------------------------------------------------------------------------------------------ `include "prj_definition.v" -// Control signals, same as in data_path.v +// Control signals, referenced in data_path.v `define pc_load 0 `define pc_sel_1 1 `define pc_sel_2 2 @@ -105,6 +105,7 @@ output READ, WRITE; input ZERO, CLK, RST; input [`DATA_INDEX_LIMIT:0] INSTRUCTION; +// Task to print instruction task print_instruction; input [`DATA_INDEX_LIMIT:0] inst; reg [5:0] opcode; @@ -127,52 +128,46 @@ begin $write("@ %6dns -> [0X%08h] ", $time, inst); case(opcode) -// R-Type - 6'h00 : begin - case(funct) - 6'h20: $write("add r[%02d], r[%02d], r[%02d];", rd, rs, rt); - 6'h22: $write("sub r[%02d], r[%02d], r[%02d];", rd, rs, rt); - 6'h2c: $write("mul r[%02d], r[%02d], r[%02d];", rd, rs, rt); - 6'h24: $write("and r[%02d], r[%02d], r[%02d];", rd, rs, rt); - 6'h25: $write("or r[%02d], r[%02d], r[%02d];", rd, rs, rt); - 6'h27: $write("nor r[%02d], r[%02d], r[%02d];", rd, rs, rt); - 6'h2a: $write("slt r[%02d], r[%02d], r[%02d];", rd, rs, rt); - 6'h01: $write("sll r[%02d], r[%02d], %2d;", rd, rs, shamt); - 6'h02: $write("srl r[%02d], 0X%02h, r[%02d];", rd, rs, shamt); - 6'h08: $write("jr r[%02d];", rs); - default: $write(""); - endcase - end + // R-Type + `OP_RTYPE: case(funct) + `FN_ADD: $write("add r[%02d], r[%02d], r[%02d];", rd, rs, rt); + `FN_SUB: $write("sub r[%02d], r[%02d], r[%02d];", rd, rs, rt); + `FN_MUL: $write("mul r[%02d], r[%02d], r[%02d];", rd, rs, rt); + `FN_AND: $write("and r[%02d], r[%02d], r[%02d];", rd, rs, rt); + `FN_OR: $write("or r[%02d], r[%02d], r[%02d];", rd, rs, rt); + `FN_NOR: $write("nor r[%02d], r[%02d], r[%02d];", rd, rs, rt); + `FN_SLT: $write("slt r[%02d], r[%02d], r[%02d];", rd, rs, rt); + `FN_SLL: $write("sll r[%02d], r[%02d], %2d;", rd, rs, shamt); + `FN_SRL: $write("srl r[%02d], 0X%02h, r[%02d];", rd, rs, shamt); + `FN_JR: $write("jr r[%02d];", rs); + default: $write(""); + endcase // I-type - 6'h08 : $write("addi r[%02d], r[%02d], 0X%04h;", rt, rs, imm); - 6'h1d : $write("muli r[%02d], r[%02d], 0X%04h;", rt, rs, imm); - 6'h0c : $write("andi r[%02d], r[%02d], 0X%04h;", rt, rs, imm); - 6'h0d : $write("ori r[%02d], r[%02d], 0X%04h;", rt, rs, imm); - 6'h0f : $write("lui r[%02d], 0X%04h;", rt, imm); - 6'h0a : $write("slti r[%02d], r[%02d], 0X%04h;", rt, rs, imm); - 6'h04 : $write("beq r[%02d], r[%02d], 0X%04h;", rt, rs, imm); - 6'h05 : $write("bne r[%02d], r[%02d], 0X%04h;", rt, rs, imm); - 6'h23 : $write("lw r[%02d], r[%02d], 0X%04h;", rt, rs, imm); - 6'h2b : $write("sw r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + `OP_ADDI: $write("addi r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + `OP_MULI: $write("muli r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + `OP_ANDI: $write("andi r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + `OP_ORI: $write("ori r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + `OP_LUI: $write("lui r[%02d], 0X%04h;", rt, imm); + `OP_SLTI: $write("slti r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + `OP_BEQ: $write("beq r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + `OP_BNE: $write("bne r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + `OP_LW: $write("lw r[%02d], r[%02d], 0X%04h;", rt, rs, imm); + `OP_SW: $write("sw r[%02d], r[%02d], 0X%04h;", rt, rs, imm); // J-Type - 6'h02 : $write("jmp 0X%07h;", addr); - 6'h03 : $write("jal 0X%07h;", addr); - 6'h1b : $write("push;"); - 6'h1c : $write("pop;"); - default: $write(""); + `OP_JMP: $write("jmp 0X%07h;", addr); + `OP_JAL: $write("jal 0X%07h;", addr); + `OP_PUSH: $write("push;"); + `OP_POP: $write("pop;"); + default: $write(""); endcase $write("\n"); end endtask -//------------------------------------- END ---------------------------------------// - reg read, write; buf (READ, read); buf (WRITE, write); -//assign READ = read; -//assign WRITE = write; reg [31:0] C; @@ -209,7 +204,7 @@ always @ (state) begin // memory read = 1'b1; write = 1'b0; - // load data from mem[PC] + // ma_sel_2: load data from mem[PC] C[`ma_sel_2] = 1'b1; end // decode - parse instruction and read values from register file @@ -226,8 +221,8 @@ always @ (state) begin print_instruction(INSTRUCTION); // loaded in previous state, set to 0 C[`ir_load] = 1'b0; - // load now - C[`sp_load] = opcode == `OP_POP; // sp is decremented before pop + // load now - sp is incremented before pop + C[`sp_load] = opcode == `OP_POP; // r1_sel_1: rs by default (0), push - r1 (1) C[`r1_sel_1] = opcode == `OP_PUSH; @@ -247,9 +242,9 @@ always @ (state) begin C[`pc_sel_3] = ~(opcode == `OP_JMP || opcode == `OP_JAL); // alu_oprn - operation to be performed by ALU - // R-type - if (opcode == `OP_RTYPE) begin - case (funct) + case (opcode) + // R-type + `OP_RTYPE: case (funct) `FN_ADD: C[`alu_oprn] = `ALU_ADD; `FN_SUB: C[`alu_oprn] = `ALU_SUB; `FN_MUL: C[`alu_oprn] = `ALU_MUL; @@ -261,26 +256,22 @@ always @ (state) begin `FN_SLT: C[`alu_oprn] = `ALU_SLT; default: C[`alu_oprn] = `ALU_NOP; endcase - end - // I-type and J-type - else begin - case (opcode) - // I-type - `OP_ADDI: C[`alu_oprn] = `ALU_ADD; // addi - `OP_MULI: C[`alu_oprn] = `ALU_MUL; // muli - `OP_ANDI: C[`alu_oprn] = `ALU_AND; // andi - `OP_ORI: C[`alu_oprn] = `ALU_OR; // ori - `OP_SLTI: C[`alu_oprn] = `ALU_SLT; // slti - `OP_BEQ: C[`alu_oprn] = `ALU_SUB; // beq - sub - `OP_BNE: C[`alu_oprn] = `ALU_SUB; // bne - sub - `OP_LW: C[`alu_oprn] = `ALU_ADD; // lw - add - `OP_SW: C[`alu_oprn] = `ALU_ADD; // sw - add - // J-type - `OP_PUSH: C[`alu_oprn] = `ALU_SUB; // push - sub - `OP_POP: C[`alu_oprn] = `ALU_ADD; // pop - add - default: C[`alu_oprn] = `ALU_NOP; - endcase - end + // I-type + `OP_ADDI: C[`alu_oprn] = `ALU_ADD; // addi + `OP_MULI: C[`alu_oprn] = `ALU_MUL; // muli + `OP_ANDI: C[`alu_oprn] = `ALU_AND; // andi + `OP_ORI: C[`alu_oprn] = `ALU_OR; // ori + `OP_SLTI: C[`alu_oprn] = `ALU_SLT; // slti + `OP_BEQ: C[`alu_oprn] = `ALU_SUB; // beq - sub + `OP_BNE: C[`alu_oprn] = `ALU_SUB; // bne - sub + `OP_LW: C[`alu_oprn] = `ALU_ADD; // lw - add + `OP_SW: C[`alu_oprn] = `ALU_ADD; // sw - add + // J-type + `OP_PUSH: C[`alu_oprn] = `ALU_SUB; // push - sub + `OP_POP: C[`alu_oprn] = `ALU_ADD; // pop - add + default: C[`alu_oprn] = `ALU_NOP; + endcase + // op1_sel_1: r1 by default (0), push or pop - sp (1) C[`op1_sel_1] = opcode == `OP_PUSH || opcode == `OP_POP; @@ -290,7 +281,7 @@ always @ (state) begin // ('nor' not availble in I-type) C[`op2_sel_2] = ~(opcode == `OP_ANDI || opcode == `OP_ORI); // op2_sel_3: op2_sel_2 for I-type (0), op2_sel_1 for R-type shift or inc/dec (1) - // (inc/dec is for sp with push or pop) + // (inc/dec is for sp with pop or push) C[`op2_sel_3] = opcode == `OP_RTYPE || opcode == `OP_PUSH || opcode == `OP_POP; // op2_sel_4: op2_sel_3 for I-type (except beq, bne) or R-type shift or inc/dec (0), else r2 (1) // i.e. r2 if R-type (except sll/srl), or bne/beq @@ -321,13 +312,14 @@ always @ (state) begin read = opcode == `OP_POP || opcode == `OP_LW; end `PROC_WB: begin - // load now - C[`sp_load] = opcode == `OP_PUSH; // sp is incremented after push // loaded in previous state, set to 0 read = 1'b0; write = 1'b0; // load now + // pc gets next instruction address C[`pc_load] = 1'b1; + // sp is decremented after push + C[`sp_load] = opcode == `OP_PUSH; // write to register file if // R-type (except jr) or I-type (except beq, bne, sw) or pop or jal C[`reg_w] = (opcode == `OP_RTYPE && funct != `FN_JR) // R-type (except jr) @@ -335,7 +327,6 @@ always @ (state) begin || opcode == `OP_LUI || opcode == `OP_SLTI || opcode == `OP_LW) // I-type (except beq, bne, sw) || (opcode == `OP_POP || opcode == `OP_JAL) // pop or jal ; - // selections // pc_sel_2: branch if equal or not equal C[`pc_sel_2] = ((opcode == `OP_BEQ) && ZERO) || ((opcode == `OP_BNE) && ~ZERO); end -- 2.47.2