From 8fa5f6a522cfaaf9479c12ae84e82d164f3f8e5a Mon Sep 17 00:00:00 2001 From: Sven Stucki Date: Tue, 29 Sep 2015 14:10:29 +0200 Subject: [PATCH] Add reg-reg and post-increment load/stores to tracer --- include/defines.sv | 8 +-- riscv_core.sv | 158 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 126 insertions(+), 40 deletions(-) diff --git a/include/defines.sv b/include/defines.sv index 0cf5caae..73ed418c 100644 --- a/include/defines.sv +++ b/include/defines.sv @@ -128,7 +128,6 @@ // RV32M `define INSTR_MUL { 7'b0000001, 10'b?, 3'b000, 5'b?, `OPCODE_OP } -/* not implemented `define INSTR_MULH { 7'b0000001, 10'b?, 3'b001, 5'b?, `OPCODE_OP } `define INSTR_MULHSU { 7'b0000001, 10'b?, 3'b010, 5'b?, `OPCODE_OP } `define INSTR_MULHU { 7'b0000001, 10'b?, 3'b011, 5'b?, `OPCODE_OP } @@ -136,14 +135,9 @@ `define INSTR_DIVU { 7'b0000001, 10'b?, 3'b101, 5'b?, `OPCODE_OP } `define INSTR_REM { 7'b0000001, 10'b?, 3'b110, 5'b?, `OPCODE_OP } `define INSTR_REMU { 7'b0000001, 10'b?, 3'b111, 5'b?, `OPCODE_OP } -*/ // PULP custom instructions - -// Post-indexed load -`define INSTR_LBPOST { 17'b?, 3'b011, 5'b?, `OPCODE_LOAD_POST } -`define INSTR_LHPOST { 17'b?, 3'b110, 5'b?, `OPCODE_LOAD_POST } -`define INSTR_LWPOST { 17'b?, 3'b111, 5'b?, `OPCODE_LOAD_POST } +`define INSTR_MAC { 2'b00, 15'b?, 3'b000, 5'b?, `OPCODE_PULP_OP } // Source/Destination register instruction index `define REG_S1 19:15 diff --git a/riscv_core.sv b/riscv_core.sv index b7c2517f..3bca35e7 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -648,16 +648,25 @@ module riscv_core // Execution trace generation // synopsys translate_off `ifdef TRACE_EXECUTION - integer f; - string fn; + integer f; + string fn; integer cycles; logic [31:0] instr; logic compressed; logic [31:0] pc; - logic [4:0] rd, rs1, rs2; - logic [31:0] rs1_value, rs2_value; + logic [4:0] rd, rs1, rs2, rs3; + logic [31:0] rs1_value, rs2_value, rs3_value; logic [31:0] imm; - string mnemonic; + string mnemonic; + + // cycle counter + always_ff @(posedge clk, negedge rst_n) + begin + if (rst_n == 1'b0) + cycles = 0; + else + cycles = cycles + 1; + end // open/close output file for writing initial @@ -688,6 +697,8 @@ module riscv_core rs1_value = id_stage_i.operand_a_fw_id; rs2 = instr[`REG_S2]; rs2_value = id_stage_i.operand_b_fw_id; + rs3 = instr[`REG_S3]; + rs3_value = id_stage_i.alu_operand_c; // special case for WFI because we don't wait for unstalling there if ((id_valid && is_decoding) || id_stage_i.controller_i.pipe_flush_i) @@ -719,15 +730,6 @@ module riscv_core `INSTR_BGE: printSBInstr("BGE"); `INSTR_BLTU: printSBInstr("BLTU"); `INSTR_BGEU: printSBInstr("BGEU"); - // LOAD - `INSTR_LB: printILInstr("LB"); - `INSTR_LBPOST: printILInstr("LBPOST"); - `INSTR_LH: printILInstr("LH"); - `INSTR_LHPOST: printILInstr("LHPOST"); - `INSTR_LW: printILInstr("LW"); - `INSTR_LWPOST: printILInstr("LWPOST"); - `INSTR_LBU: printILInstr("LBU"); - `INSTR_LHU: printILInstr("LHU"); // STORE `INSTR_SB: printSInstr("SB"); `INSTR_SH: printSInstr("SH"); @@ -776,11 +778,20 @@ module riscv_core `INSTR_RDINSTRETH: printRDInstr("RDINSTRETH"); // RV32M `INSTR_MUL: printRInstr("MUL"); - /* `INSTR_MULH: printRInstr("MULH"); `INSTR_MULHSU: printRInstr("MULHSU"); `INSTR_MULHU: printRInstr("MULHU"); - */ + `INSTR_DIV: printRInstr("DIV"); + `INSTR_DIVU: printRInstr("DIVU"); + `INSTR_REM: printRInstr("REM"); + `INSTR_REMU: printRInstr("REMU"); + // PULP specific + `INSTR_MAC: printR3Instr("MAC"); + // opcodes with custom decoding + {25'b?, `OPCODE_LOAD}: printLoadInstr(); + {25'b?, `OPCODE_LOAD_POST}: printLoadInstr(); + {25'b?, `OPCODE_STORE}: printStoreInstr(); + {25'b?, `OPCODE_STORE_POST}: printStoreInstr(); default: printMnemonic("INVALID"); endcase // unique case (instr) @@ -788,14 +799,6 @@ module riscv_core end end // always @ (posedge clk) - always_ff @(posedge clk, negedge rst_n) - begin - if (rst_n == 1'b0) - cycles = 0; - else - cycles = cycles + 1; - end - function void printMnemonic(input string mnemonic); begin riscv_core.mnemonic = mnemonic; @@ -819,6 +822,14 @@ module riscv_core end endfunction // printRInstr + function void printR3Instr(input string mnemonic); + begin + riscv_core.mnemonic = mnemonic; + $fdisplay(f, "%7s\tx%0d, x%0d (0x%h), x%0d (0x%h), x%0d (0x%h)", mnemonic, + rd, rs1, rs1_value, rs2, rs2_value, rs3, rs3_value); + end + endfunction // printRInstr + function void printIInstr(input string mnemonic); begin riscv_core.mnemonic = mnemonic; @@ -828,15 +839,6 @@ module riscv_core end endfunction // printIInstr - function void printILInstr(input string mnemonic); - begin - riscv_core.mnemonic = mnemonic; - imm = id_stage_i.imm_i_type; - $fdisplay(f, "%7s\tx%0d, x%0d (0x%h), 0x%0h (imm) (-> 0x%h)", mnemonic, - rd, rs1, rs1_value, imm, imm+rs1_value); - end - endfunction // printILInstr - function void printSInstr(input string mnemonic); begin riscv_core.mnemonic = mnemonic; @@ -886,6 +888,96 @@ module riscv_core end endfunction // printCSRInstr + function void printLoadInstr(); + string mnemonic; + logic [2:0] size; + begin + // detect reg-reg load and find size + size = instr[14:12]; + if (instr[14:12] == 3'b111) + size = instr[30:28]; + case (size) + 3'b000: mnemonic = "LB"; + 3'b001: mnemonic = "LH"; + 3'b010: mnemonic = "LW"; + 3'b100: mnemonic = "LBU"; + 3'b101: mnemonic = "LHU"; + 3'b011, + 3'b110, + 3'b111: begin + printMnemonic("INVALID"); + return; + end + endcase + + // compose mnemonic + if (instr[14:12] == 3'b111) + mnemonic = {mnemonic, "RR"}; + if (instr[6:0] == `OPCODE_LOAD_POST) + mnemonic = {mnemonic, "POST"}; + riscv_core.mnemonic = mnemonic; + + if (instr[14:12] != 3'b111) begin + // regular load + imm = id_stage_i.imm_i_type; + if (instr[6:0] != `OPCODE_LOAD_POST) + $fdisplay(f, "%7s\tx%0d, x%0d (0x%h), 0x%0h (imm) (-> 0x%h)", + mnemonic, rd, rs1, rs1_value, imm, imm+rs1_value); + else + $fdisplay(f, "%7s\tx%0d, x%0d! (0x%h), 0x%0h (imm) (-> 0x%h)", + mnemonic, rd, rs1, rs1_value, imm, rs1_value); + end else begin + // reg-reg load + if (instr[6:0] != `OPCODE_LOAD_POST) + $fdisplay(f, "%7s\tx%0d, x%0d (0x%h), x%0d (0x%h) (-> 0x%h)", mnemonic, + rd, rs1, rs1_value, rs2, rs2_value, rs1_value+rs2_value); + else + $fdisplay(f, "%7s\tx%0d, x%0d! (0x%h), x%0d (0x%h) (-> 0x%h)", mnemonic, + rd, rs1, rs1_value, rs2, rs2_value, rs1_value); + end + end + endfunction + + function void printStoreInstr(); + string mnemonic; + begin + case (instr[13:12]) + 2'b00: mnemonic = "SB"; + 2'b01: mnemonic = "SH"; + 2'b10: mnemonic = "SW"; + 2'b11: begin + printMnemonic("INVALID"); + return; + end + endcase + + // compose mnemonic + if (instr[14]) + mnemonic = {mnemonic, "RR"}; + if (instr[6:0] == `OPCODE_STORE_POST) + mnemonic = {mnemonic, "POST"}; + riscv_core.mnemonic = mnemonic; + + if (instr[14] == 1'b0) begin + // regular store + imm = id_stage_i.imm_s_type; + if (instr[6:0] != `OPCODE_STORE_POST) + $fdisplay(f, "%7s\tx%0d (0x%h), x%0d (0x%h), 0x%0h (imm) (-> 0x%h)", + mnemonic, rs1, rs1_value, rs2, rs2_value, imm, imm+rs1_value); + else + $fdisplay(f, "%7s\tx%0d! (0x%h), x%0d (0x%h), 0x%0h (imm) (-> 0x%h)", + mnemonic, rs1, rs1_value, rs2, rs2_value, imm, rs1_value); + end else begin + // reg-reg store + if (instr[6:0] != `OPCODE_STORE_POST) + $fdisplay(f, "%7s\tx%0d (0x%h), x%0d (0x%h), x%0d (0x%h) (-> 0x%h)", mnemonic, + rs1, rs1_value, rs2, rs2_value, rs3, rs3_value, rs1_value+rs3_value); + else + $fdisplay(f, "%7s\tx%0d! (0x%h), x%0d (0x%h), x%0d (0x%h) (-> 0x%h)", mnemonic, + rs1, rs1_value, rs2, rs2_value, rs3, rs3_value, rs1_value); + end + end + endfunction // printSInstr `endif // TRACE_EXECUTION // synopsys translate_on `endif