1 |
3 |
sergeykhbr |
/**
|
2 |
|
|
* @file
|
3 |
|
|
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved.
|
4 |
|
|
* @author Sergey Khabarov - sergeykhbr@gmail.com
|
5 |
|
|
* @brief CPU Instruction Decoder stage.
|
6 |
|
|
*/
|
7 |
|
|
|
8 |
|
|
#ifndef __DEBUGGER_RIVERLIB_DECODER_H__
|
9 |
|
|
#define __DEBUGGER_RIVERLIB_DECODER_H__
|
10 |
|
|
|
11 |
|
|
#include <systemc.h>
|
12 |
|
|
#include "../river_cfg.h"
|
13 |
|
|
|
14 |
|
|
namespace debugger {
|
15 |
|
|
|
16 |
|
|
const uint8_t OPCODE_LB = 0x00; // 00000: LB, LH, LW, LD, LBU, LHU, LWU
|
17 |
|
|
const uint8_t OPCODE_FENCE = 0x03; // 00011: FENCE, FENCE_I
|
18 |
|
|
const uint8_t OPCODE_ADDI = 0x04; // 00100: ADDI, ANDI, ORI, SLLI, SLTI, SLTIU, SRAI, SRLI, XORI
|
19 |
|
|
const uint8_t OPCODE_AUIPC = 0x05; // 00101: AUIPC
|
20 |
|
|
const uint8_t OPCODE_ADDIW = 0x06; // 00110: ADDIW, SLLIW, SRAIW, SRLIW
|
21 |
|
|
const uint8_t OPCODE_SB = 0x08; // 01000: SB, SH, SW, SD
|
22 |
|
|
const uint8_t OPCODE_ADD = 0x0C; // 01100: ADD, AND, OR, SLT, SLTU, SLL, SRA, SRL, SUB, XOR, DIV, DIVU, MUL, REM, REMU
|
23 |
|
|
const uint8_t OPCODE_LUI = 0x0D; // 01101: LUI
|
24 |
|
|
const uint8_t OPCODE_ADDW = 0x0E; // 01110: ADDW, SLLW, SRAW, SRLW, SUBW, DIVW, DIVUW, MULW, REMW, REMUW
|
25 |
|
|
const uint8_t OPCODE_BEQ = 0x18; // 11000: BEQ, BNE, BLT, BGE, BLTU, BGEU
|
26 |
|
|
const uint8_t OPCODE_JALR = 0x19; // 11001: JALR
|
27 |
|
|
const uint8_t OPCODE_JAL = 0x1B; // 11011: JAL
|
28 |
|
|
const uint8_t OPCODE_CSRR = 0x1C; // 11100: CSRRC, CSRRCI, CSRRS, CSRRSI, CSRRW, CSRRWI, URET, SRET, HRET, MRET
|
29 |
4 |
sergeykhbr |
// Compressed instruction set
|
30 |
|
|
const uint8_t OPCODE_C_ADDI4SPN = 0x00;
|
31 |
|
|
const uint8_t OPCODE_C_NOP_ADDI = 0x01;
|
32 |
|
|
const uint8_t OPCODE_C_SLLI = 0x02;
|
33 |
|
|
const uint8_t OPCODE_C_JAL_ADDIW = 0x05;
|
34 |
|
|
const uint8_t OPCODE_C_LW = 0x08;
|
35 |
|
|
const uint8_t OPCODE_C_LI = 0x09;
|
36 |
|
|
const uint8_t OPCODE_C_LWSP = 0x0A;
|
37 |
|
|
const uint8_t OPCODE_C_LD = 0x0C;
|
38 |
|
|
const uint8_t OPCODE_C_ADDI16SP_LUI = 0xD;
|
39 |
|
|
const uint8_t OPCODE_C_LDSP = 0x0E;
|
40 |
|
|
const uint8_t OPCODE_C_MATH = 0x11;
|
41 |
|
|
const uint8_t OPCODE_C_JR_MV_EBREAK_JALR_ADD = 0x12;
|
42 |
|
|
const uint8_t OPCODE_C_J = 0x15;
|
43 |
|
|
const uint8_t OPCODE_C_SW = 0x18;
|
44 |
|
|
const uint8_t OPCODE_C_BEQZ = 0x19;
|
45 |
|
|
const uint8_t OPCODE_C_SWSP = 0x1A;
|
46 |
|
|
const uint8_t OPCODE_C_SD = 0x1C;
|
47 |
|
|
const uint8_t OPCODE_C_BNEZ = 0x1D;
|
48 |
|
|
const uint8_t OPCODE_C_SDSP = 0x1E;
|
49 |
3 |
sergeykhbr |
|
50 |
|
|
SC_MODULE(InstrDecoder) {
|
51 |
|
|
sc_in<bool> i_clk;
|
52 |
|
|
sc_in<bool> i_nrst; // Reset active low
|
53 |
|
|
sc_in<bool> i_any_hold; // Hold pipeline by any reason
|
54 |
|
|
sc_in<bool> i_f_valid; // Fetch input valid
|
55 |
|
|
sc_in<sc_uint<BUS_ADDR_WIDTH>> i_f_pc; // Fetched pc
|
56 |
|
|
sc_in<sc_uint<32>> i_f_instr; // Fetched instruction value
|
57 |
|
|
|
58 |
|
|
sc_out<bool> o_valid; // Current output values are valid
|
59 |
|
|
sc_out<sc_uint<BUS_ADDR_WIDTH>> o_pc; // Current instruction pointer value
|
60 |
|
|
sc_out<sc_uint<32>> o_instr; // Current instruction value
|
61 |
|
|
sc_out<bool> o_memop_store; // Store to memory operation
|
62 |
|
|
sc_out<bool> o_memop_load; // Load from memoru operation
|
63 |
|
|
sc_out<bool> o_memop_sign_ext; // Load memory value with sign extending
|
64 |
|
|
sc_out<sc_uint<2>> o_memop_size; // Memory transaction size
|
65 |
|
|
sc_out<bool> o_rv32; // 32-bits instruction
|
66 |
4 |
sergeykhbr |
sc_out<bool> o_compressed; // C-type instruction
|
67 |
3 |
sergeykhbr |
sc_out<bool> o_unsigned_op; // Unsigned operands
|
68 |
|
|
sc_out<sc_bv<ISA_Total>> o_isa_type; // Instruction format accordingly with ISA
|
69 |
|
|
sc_out<sc_bv<Instr_Total>> o_instr_vec; // One bit per decoded instruction bus
|
70 |
|
|
sc_out<bool> o_exception;
|
71 |
|
|
|
72 |
|
|
void comb();
|
73 |
|
|
void registers();
|
74 |
|
|
|
75 |
|
|
SC_HAS_PROCESS(InstrDecoder);
|
76 |
|
|
|
77 |
|
|
InstrDecoder(sc_module_name name_);
|
78 |
|
|
|
79 |
|
|
void generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd);
|
80 |
|
|
|
81 |
|
|
private:
|
82 |
|
|
struct RegistersType {
|
83 |
|
|
sc_signal<bool> valid;
|
84 |
|
|
sc_signal<sc_uint<BUS_ADDR_WIDTH>> pc;
|
85 |
|
|
sc_bv<ISA_Total> isa_type;
|
86 |
|
|
sc_bv<Instr_Total> instr_vec;
|
87 |
|
|
sc_signal<sc_uint<32>> instr;
|
88 |
|
|
sc_signal<bool> memop_store;
|
89 |
|
|
sc_signal<bool> memop_load;
|
90 |
|
|
sc_signal<bool> memop_sign_ext;
|
91 |
|
|
sc_signal<sc_uint<2>> memop_size;
|
92 |
|
|
sc_signal<bool> unsigned_op;
|
93 |
|
|
sc_signal<bool> rv32;
|
94 |
4 |
sergeykhbr |
sc_signal<bool> compressed;
|
95 |
3 |
sergeykhbr |
|
96 |
|
|
sc_signal<bool> instr_unimplemented;
|
97 |
|
|
} v, r;
|
98 |
|
|
};
|
99 |
|
|
|
100 |
|
|
|
101 |
|
|
} // namespace debugger
|
102 |
|
|
|
103 |
|
|
#endif // __DEBUGGER_RIVERLIB_DECODER_H__
|