diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-02-16 20:55:24 +0200 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-02-16 20:55:24 +0200 |
commit | 82dec45fd786831f791b17b84aedb4d99b5ca25d (patch) | |
tree | 5b98b452edc749b938a67368c9020244ca40595e /src/rv2insn.sv | |
parent | 0141d830f3326594f159c627dbbc284fdef27674 (diff) | |
download | ttarv32-82dec45fd786831f791b17b84aedb4d99b5ca25d.tar.gz ttarv32-82dec45fd786831f791b17b84aedb4d99b5ca25d.zip |
add initial risc-v -> tta translation block
Diffstat (limited to 'src/rv2insn.sv')
-rw-r--r-- | src/rv2insn.sv | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/rv2insn.sv b/src/rv2insn.sv new file mode 100644 index 0000000..1d9996c --- /dev/null +++ b/src/rv2insn.sv @@ -0,0 +1,107 @@ +`include "common.svh" + +module rv2insn #( + parameter QUE_DEPTH, + parameter ALU_COUNT +)( + input clk_i, + input rst_ni, + input xlen_t pc_i, + input rv_t[QUE_DEPTH-1:0] rv_i, + output insn_t[QUE_DEPTH-1:0] que_o +); + +typedef logic[$clog2(ALU_COUNT):0] alu_counter_t; + +alu_counter_t alu_counter_r; +alu_counter_t alu_counter; + +typedef struct packed { + insn_t insn; + alu_counter_t alu_counter; +} decode_out_t; + +function automatic insn_t halt(); + /* TODO come up with some proper instruction here */ + return -1; +endfunction + +function automatic alu_counter_t next_alu(alu_counter_t alu_counter); + return (alu_counter + 1) % ALU_COUNT; +endfunction + +function automatic decode_out_t op_imm(xlen_t pc, itype_t rv, alu_counter_t alu_counter); + alu_counter_t fu = next_alu(alu_counter); + unique case (rv.funct3) + 3'b000: return {{NOP, NOP}, + {`rn(rv.rs1), `alu(fu)}, + {`alu(fu), `rn(rv.rd)}, + ALU_ADDI, imm_t'(signed'(rv.imm)), fu}; + + default: return {halt(), fu}; + endcase + + return 0; +endfunction + +function automatic decode_out_t op(xlen_t pc, rtype_t rv, alu_counter_t alu_counter); + alu_counter_t fu = next_alu(alu_counter); + unique case (rv.funct3) + 3'b000: begin + unique case (rv.funct7) + 7'b0000000: + return {{`rn(rv.rs1), `alu(fu)}, + {`rn(rv.rs2), `alu(fu)}, + {`alu(fu), `rn(rv.rd)}, + ALU_ADD, imm_t'(0), fu}; + 7'b0100000: + return {{`rn(rv.rs1), `alu(fu)}, + {`rn(rv.rs2), `alu(fu)}, + {`alu(fu), `rn(rv.rd)}, + ALU_SUB, imm_t'(0), fu}; + + default: return {halt(), fu}; + endcase + end + default: return {halt(), fu}; + endcase +endfunction + +function automatic decode_out_t decode(xlen_t pc, rv_t rv, alu_counter_t alu_counter); + unique case (rv[`RV_OP_FIELD]) + OP_IMM: return op_imm (pc, rv, alu_counter); + OP: return op (pc, rv, alu_counter); + default: return {halt(), alu_counter}; + endcase +endfunction + +typedef struct packed { + insn_t[QUE_DEPTH-1:0] que; + alu_counter_t alu_counter; +} stages_out_t; + +function automatic stages_out_t stages(int i, xlen_t pc, + rv_t[QUE_DEPTH-1:0] rv, insn_t[QUE_DEPTH-1:0] que, alu_counter_t alu_counter); + if (i < QUE_DEPTH) begin + decode_out_t out = decode(pc + i, rv[i], alu_counter); + que[i] = out.insn; + return stages(i + 1, pc, rv, que, out.alu_counter); + end else begin + return {que, alu_counter}; + end +endfunction + +always_comb begin + stages_out_t out = stages(0, pc_i, rv_i, '0, alu_counter_r); + alu_counter = out.alu_counter; + que_o = out.que; +end + +always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + alu_counter_r <= 0; + end else begin + alu_counter_r <= alu_counter; + end +end +endmodule |