| 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__
|