| 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 pipeline implementation.
 | 
      
         | 6 |  |  |  */
 | 
      
         | 7 |  |  |  
 | 
      
         | 8 |  |  | #ifndef __DEBUGGER_RIVERLIB_PROC_H__
 | 
      
         | 9 |  |  | #define __DEBUGGER_RIVERLIB_PROC_H__
 | 
      
         | 10 |  |  |  
 | 
      
         | 11 |  |  | #include <systemc.h>
 | 
      
         | 12 |  |  | #include "../river_cfg.h"
 | 
      
         | 13 |  |  | #include "fetch.h"
 | 
      
         | 14 |  |  | #include "decoder.h"
 | 
      
         | 15 |  |  | #include "execute.h"
 | 
      
         | 16 |  |  | #include "memaccess.h"
 | 
      
         | 17 |  |  | #include "execute.h"
 | 
      
         | 18 |  |  | #include "regibank.h"
 | 
      
         | 19 |  |  | #include "csr.h"
 | 
      
         | 20 |  |  | #include "br_predic.h"
 | 
      
         | 21 |  |  | #include "dbg_port.h"
 | 
      
         | 22 |  |  | #include <fstream>
 | 
      
         | 23 |  |  |  
 | 
      
         | 24 |  |  |  
 | 
      
         | 25 |  |  | namespace debugger {
 | 
      
         | 26 |  |  |  
 | 
      
         | 27 |  |  | SC_MODULE(Processor) {
 | 
      
         | 28 |  |  |     sc_in<bool> i_clk;                                  // CPU clock
 | 
      
         | 29 |  |  |     sc_in<bool> i_nrst;                                 // Reset. Active LOW
 | 
      
         | 30 |  |  |     // Control path:
 | 
      
         | 31 |  |  |     sc_in<bool> i_req_ctrl_ready;                       // ICache is ready to accept request
 | 
      
         | 32 |  |  |     sc_out<bool> o_req_ctrl_valid;                      // Request to ICache is valid
 | 
      
         | 33 |  |  |     sc_out<sc_uint<BUS_ADDR_WIDTH>> o_req_ctrl_addr;    // Requesting address to ICache
 | 
      
         | 34 |  |  |     sc_in<bool> i_resp_ctrl_valid;                      // ICache response is valid
 | 
      
         | 35 |  |  |     sc_in<sc_uint<BUS_ADDR_WIDTH>> i_resp_ctrl_addr;    // Response address must be equal to the latest request address
 | 
      
         | 36 |  |  |     sc_in<sc_uint<32>> i_resp_ctrl_data;                // Read value
 | 
      
         | 37 |  |  |     sc_out<bool> o_resp_ctrl_ready;                     // Core is ready to accept response from ICache
 | 
      
         | 38 |  |  |     // Data path:
 | 
      
         | 39 |  |  |     sc_in<bool> i_req_data_ready;                       // DCache is ready to accept request
 | 
      
         | 40 |  |  |     sc_out<bool> o_req_data_valid;                      // Request to DCache is valid
 | 
      
         | 41 |  |  |     sc_out<bool> o_req_data_write;                      // Read/Write transaction
 | 
      
         | 42 |  |  |     sc_out<sc_uint<2>> o_req_data_size;                 // Size [Bytes]: 0=1B; 1=2B; 2=4B; 3=8B
 | 
      
         | 43 |  |  |     sc_out<sc_uint<BUS_ADDR_WIDTH>> o_req_data_addr;    // Requesting address to DCache
 | 
      
         | 44 |  |  |     sc_out<sc_uint<RISCV_ARCH>> o_req_data_data;        // Writing value
 | 
      
         | 45 |  |  |     sc_in<bool> i_resp_data_valid;                      // DCache response is valid
 | 
      
         | 46 |  |  |     sc_in<sc_uint<BUS_ADDR_WIDTH>> i_resp_data_addr;    // DCache response address must be equal to the latest request address
 | 
      
         | 47 |  |  |     sc_in<sc_uint<RISCV_ARCH>> i_resp_data_data;        // Read value
 | 
      
         | 48 |  |  |     sc_out<bool> o_resp_data_ready;                     // Core is ready to accept response from DCache
 | 
      
         | 49 |  |  |     // External interrupt pin
 | 
      
         | 50 |  |  |     sc_in<bool> i_ext_irq;                              // PLIC interrupt accordingly with spec
 | 
      
         | 51 |  |  |     sc_out<sc_uint<64>> o_time;                         // Clock/Step counter depending attribute "GenerateRef"
 | 
      
         | 52 |  |  |     // Debug interface
 | 
      
         | 53 |  |  |     sc_in<bool> i_dport_valid;                          // Debug access from DSU is valid
 | 
      
         | 54 |  |  |     sc_in<bool> i_dport_write;                          // Write command flag
 | 
      
         | 55 |  |  |     sc_in<sc_uint<2>> i_dport_region;                   // Registers region ID: 0=CSR; 1=IREGS; 2=Control
 | 
      
         | 56 |  |  |     sc_in<sc_uint<12>> i_dport_addr;                    // Register idx
 | 
      
         | 57 |  |  |     sc_in<sc_uint<RISCV_ARCH>> i_dport_wdata;           // Write value
 | 
      
         | 58 |  |  |     sc_out<bool> o_dport_ready;                         // Response is ready
 | 
      
         | 59 |  |  |     sc_out<sc_uint<RISCV_ARCH>> o_dport_rdata;          // Response value
 | 
      
         | 60 |  |  |     // Cache debug signals:
 | 
      
         | 61 |  |  |     sc_in<sc_uint<2>> i_istate;                         // ICache transaction state
 | 
      
         | 62 |  |  |     sc_in<sc_uint<2>> i_dstate;                         // DCache transaction state
 | 
      
         | 63 |  |  |     sc_in<sc_uint<2>> i_cstate;                         // CacheTop state machine value
 | 
      
         | 64 |  |  |  
 | 
      
         | 65 |  |  |     void comb();
 | 
      
         | 66 |  |  |     void negedge_dbg_print();
 | 
      
         | 67 |  |  |     void generateRef(bool v);
 | 
      
         | 68 |  |  |     void generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd);
 | 
      
         | 69 |  |  |  
 | 
      
         | 70 |  |  |     SC_HAS_PROCESS(Processor);
 | 
      
         | 71 |  |  |  
 | 
      
         | 72 |  |  |     Processor(sc_module_name name_);
 | 
      
         | 73 |  |  |     virtual ~Processor();
 | 
      
         | 74 |  |  |  
 | 
      
         | 75 |  |  | private:
 | 
      
         | 76 |  |  |     struct FetchType {
 | 
      
         | 77 |  |  |         sc_signal<bool> req_fire;
 | 
      
         | 78 |  |  |         sc_signal<bool> valid;
 | 
      
         | 79 |  |  |         sc_signal<sc_uint<BUS_ADDR_WIDTH>> pc;
 | 
      
         | 80 |  |  |         sc_signal<sc_uint<32>> instr;
 | 
      
         | 81 |  |  |         sc_signal<bool> imem_req_valid;
 | 
      
         | 82 |  |  |         sc_signal<sc_uint<BUS_ADDR_WIDTH>> imem_req_addr;
 | 
      
         | 83 |  |  |         sc_signal<bool> predict_miss;
 | 
      
         | 84 |  |  |         sc_signal<bool> pipeline_hold;
 | 
      
         | 85 |  |  |         sc_signal<sc_biguint<DBG_FETCH_TRACE_SIZE*64>> instr_buf;
 | 
      
         | 86 |  |  |     };
 | 
      
         | 87 |  |  |  
 | 
      
         | 88 |  |  |     struct InstructionDecodeType {
 | 
      
         | 89 |  |  |         sc_signal<sc_uint<BUS_ADDR_WIDTH>> pc;
 | 
      
         | 90 |  |  |         sc_signal<sc_uint<32>> instr;
 | 
      
         | 91 |  |  |         sc_signal<bool> instr_valid;
 | 
      
         | 92 |  |  |         sc_signal<bool> memop_store;
 | 
      
         | 93 |  |  |         sc_signal<bool> memop_load;
 | 
      
         | 94 |  |  |         sc_signal<bool> memop_sign_ext;
 | 
      
         | 95 |  |  |         sc_signal<sc_uint<2>> memop_size;
 | 
      
         | 96 |  |  |         sc_signal<bool> rv32;                       // 32-bits instruction
 | 
      
         | 97 |  |  |         sc_signal<bool> unsigned_op;                // Unsigned operands
 | 
      
         | 98 |  |  |         sc_signal<sc_bv<ISA_Total>> isa_type;
 | 
      
         | 99 |  |  |         sc_signal<sc_bv<Instr_Total>> instr_vec;
 | 
      
         | 100 |  |  |         sc_signal<bool> exception;
 | 
      
         | 101 |  |  |     };
 | 
      
         | 102 |  |  |  
 | 
      
         | 103 |  |  |     struct ExecuteType {
 | 
      
         | 104 |  |  |         sc_signal<bool> valid;
 | 
      
         | 105 |  |  |         sc_signal<sc_uint<32>> instr;
 | 
      
         | 106 |  |  |         sc_signal<sc_uint<BUS_ADDR_WIDTH>> pc;
 | 
      
         | 107 |  |  |         sc_signal<sc_uint<BUS_ADDR_WIDTH>> npc;
 | 
      
         | 108 |  |  |  
 | 
      
         | 109 |  |  |         sc_signal<sc_uint<5>> radr1;
 | 
      
         | 110 |  |  |         sc_signal<sc_uint<5>> radr2;
 | 
      
         | 111 |  |  |         sc_signal<sc_uint<5>> res_addr;
 | 
      
         | 112 |  |  |         sc_signal<sc_uint<RISCV_ARCH>> res_data;
 | 
      
         | 113 |  |  |         sc_signal<bool> trap_ena;                    // Trap pulse
 | 
      
         | 114 |  |  |         sc_signal<sc_uint<5>> trap_code;             // bit[4] : 1=interrupt; 0=exception; bits[3:0]=code
 | 
      
         | 115 |  |  |         sc_signal<sc_uint<BUS_ADDR_WIDTH>> trap_pc;  // trap on pc
 | 
      
         | 116 |  |  |         sc_signal<bool> xret;
 | 
      
         | 117 |  |  |         sc_signal<sc_uint<12>> csr_addr;
 | 
      
         | 118 |  |  |         sc_signal<bool> csr_wena;
 | 
      
         | 119 |  |  |         sc_signal<sc_uint<RISCV_ARCH>> csr_wdata;
 | 
      
         | 120 |  |  |  
 | 
      
         | 121 |  |  |         sc_signal<bool> memop_sign_ext;
 | 
      
         | 122 |  |  |         sc_signal<bool> memop_load;
 | 
      
         | 123 |  |  |         sc_signal<bool> memop_store;
 | 
      
         | 124 |  |  |         sc_signal<sc_uint<2>> memop_size;
 | 
      
         | 125 |  |  |         sc_signal<sc_uint<BUS_ADDR_WIDTH>> memop_addr;
 | 
      
         | 126 |  |  |         sc_signal<bool> pipeline_hold;           // Hold pipeline from Execution stage
 | 
      
         | 127 |  |  |         sc_signal<bool> breakpoint;
 | 
      
         | 128 |  |  |         sc_signal<bool> call;                       // pseudo-instruction CALL
 | 
      
         | 129 |  |  |         sc_signal<bool> ret;                        // pseudo-instruction RET
 | 
      
         | 130 |  |  |     };
 | 
      
         | 131 |  |  |  
 | 
      
         | 132 |  |  |     struct MemoryType {
 | 
      
         | 133 |  |  |         sc_signal<bool> valid;
 | 
      
         | 134 |  |  |         sc_signal<sc_uint<32>> instr;
 | 
      
         | 135 |  |  |         sc_signal<sc_uint<BUS_ADDR_WIDTH>> pc;
 | 
      
         | 136 |  |  |         sc_signal<bool> pipeline_hold;
 | 
      
         | 137 |  |  |     };
 | 
      
         | 138 |  |  |  
 | 
      
         | 139 |  |  |     struct WriteBackType {
 | 
      
         | 140 |  |  |         sc_signal<sc_uint<BUS_ADDR_WIDTH>> pc;
 | 
      
         | 141 |  |  |         sc_signal<bool> wena;
 | 
      
         | 142 |  |  |         sc_signal<sc_uint<5>> waddr;
 | 
      
         | 143 |  |  |         sc_signal<sc_uint<RISCV_ARCH>> wdata;
 | 
      
         | 144 |  |  |     };
 | 
      
         | 145 |  |  |  
 | 
      
         | 146 |  |  |     struct IntRegsType {
 | 
      
         | 147 |  |  |         sc_signal<sc_uint<RISCV_ARCH>> rdata1;
 | 
      
         | 148 |  |  |         sc_signal<sc_uint<RISCV_ARCH>> rdata2;
 | 
      
         | 149 |  |  |         sc_signal<sc_uint<RISCV_ARCH>> dport_rdata;
 | 
      
         | 150 |  |  |         sc_signal<sc_uint<RISCV_ARCH>> ra;      // Return address
 | 
      
         | 151 |  |  |     } ireg;
 | 
      
         | 152 |  |  |  
 | 
      
         | 153 |  |  |     struct CsrType {
 | 
      
         | 154 |  |  |         sc_signal<sc_uint<RISCV_ARCH>> rdata;
 | 
      
         | 155 |  |  |         sc_signal<sc_uint<RISCV_ARCH>> dport_rdata;
 | 
      
         | 156 |  |  |  
 | 
      
         | 157 |  |  |         sc_signal<bool> ie;                     // Interrupt enable bit
 | 
      
         | 158 |  |  |         sc_signal<sc_uint<BUS_ADDR_WIDTH>> mtvec;// Interrupt descriptor table
 | 
      
         | 159 |  |  |         sc_signal<sc_uint<2>> mode;             // Current processor mode
 | 
      
         | 160 |  |  |     } csr;
 | 
      
         | 161 |  |  |  
 | 
      
         | 162 |  |  |     struct DebugType {
 | 
      
         | 163 |  |  |         sc_signal<sc_uint<12>> core_addr;           // Address of the sub-region register
 | 
      
         | 164 |  |  |         sc_signal<sc_uint<RISCV_ARCH>> core_wdata;  // Write data
 | 
      
         | 165 |  |  |         sc_signal<bool> csr_ena;                    // Region 0: Access to CSR bank is enabled.
 | 
      
         | 166 |  |  |         sc_signal<bool> csr_write;                  // Region 0: CSR write enable
 | 
      
         | 167 |  |  |         sc_signal<bool> ireg_ena;                   // Region 1: Access to integer register bank is enabled
 | 
      
         | 168 |  |  |         sc_signal<bool> ireg_write;                 // Region 1: Integer registers bank write pulse
 | 
      
         | 169 |  |  |         sc_signal<bool> npc_write;                  // Region 1: npc write enable
 | 
      
         | 170 |  |  |         sc_signal<bool> halt;                       // Halt signal is equal to hold pipeline
 | 
      
         | 171 |  |  |         sc_signal<sc_uint<64>> clock_cnt;           // Number of clocks excluding halt state
 | 
      
         | 172 |  |  |         sc_signal<sc_uint<64>> executed_cnt;        // Number of executed instruction
 | 
      
         | 173 |  |  |         sc_signal<bool> break_mode;                          // Behaviour on EBREAK instruction: 0 = halt; 1 = generate trap
 | 
      
         | 174 |  |  |         sc_signal<bool> br_fetch_valid;                      // Fetch injection address/instr are valid
 | 
      
         | 175 |  |  |         sc_signal<sc_uint<BUS_ADDR_WIDTH>> br_address_fetch; // Fetch injection address to skip ebreak instruciton only once
 | 
      
         | 176 |  |  |         sc_signal<sc_uint<32>> br_instr_fetch;               // Real instruction value that was replaced by ebreak
 | 
      
         | 177 |  |  |     } dbg;
 | 
      
         | 178 |  |  |  
 | 
      
         | 179 |  |  |     /** 5-stages CPU pipeline */
 | 
      
         | 180 |  |  |     struct PipelineType {
 | 
      
         | 181 |  |  |         FetchType f;                            // Fetch instruction stage
 | 
      
         | 182 |  |  |         InstructionDecodeType d;                // Decode instruction stage
 | 
      
         | 183 |  |  |         ExecuteType e;                          // Execute instruction
 | 
      
         | 184 |  |  |         MemoryType m;                           // Memory load/store
 | 
      
         | 185 |  |  |         WriteBackType w;                        // Write back registers value
 | 
      
         | 186 |  |  |     } w;
 | 
      
         | 187 |  |  |  
 | 
      
         | 188 |  |  |     sc_signal<sc_uint<BUS_ADDR_WIDTH>> wb_npc_predict;
 | 
      
         | 189 |  |  |  
 | 
      
         | 190 |  |  |     sc_signal<sc_uint<5>> wb_ireg_dport_addr;
 | 
      
         | 191 |  |  |     sc_signal<sc_uint<BUS_ADDR_WIDTH>> wb_exec_dport_npc;
 | 
      
         | 192 |  |  |  
 | 
      
         | 193 |  |  |     sc_signal<bool> w_fetch_pipeline_hold;
 | 
      
         | 194 |  |  |     sc_signal<bool> w_any_pipeline_hold;
 | 
      
         | 195 |  |  |     sc_signal<bool> w_exec_pipeline_hold;
 | 
      
         | 196 |  |  |  
 | 
      
         | 197 |  |  |     InstrFetch *fetch0;
 | 
      
         | 198 |  |  |     InstrDecoder *dec0;
 | 
      
         | 199 |  |  |     InstrExecute *exec0;
 | 
      
         | 200 |  |  |     MemAccess *mem0;
 | 
      
         | 201 |  |  |  
 | 
      
         | 202 |  |  |     BranchPredictor *predic0;
 | 
      
         | 203 |  |  |     RegIntBank *iregs0;
 | 
      
         | 204 |  |  |     CsrRegs *csr0;
 | 
      
         | 205 |  |  |  
 | 
      
         | 206 |  |  |     DbgPort *dbg0;
 | 
      
         | 207 |  |  |  
 | 
      
         | 208 |  |  |     /** Used only for reference trace generation to compare with
 | 
      
         | 209 |  |  |         functional model */
 | 
      
         | 210 |  |  |     bool generate_ref_;
 | 
      
         | 211 |  |  |     char tstr[1024];
 | 
      
         | 212 |  |  |     ofstream *reg_dbg;
 | 
      
         | 213 |  |  |     ofstream *mem_dbg;
 | 
      
         | 214 |  |  |     bool mem_dbg_write_flag;
 | 
      
         | 215 |  |  |     uint64_t dbg_mem_value_mask;
 | 
      
         | 216 |  |  |     uint64_t dbg_mem_write_value;
 | 
      
         | 217 |  |  | };
 | 
      
         | 218 |  |  |  
 | 
      
         | 219 |  |  |  
 | 
      
         | 220 |  |  | }  // namespace debugger
 | 
      
         | 221 |  |  |  
 | 
      
         | 222 |  |  | #endif  // __DEBUGGER_RIVERLIB_PROC_H__
 |