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 Memory Access stage.
|
6 |
|
|
*/
|
7 |
|
|
|
8 |
|
|
#ifndef __DEBUGGER_RIVERLIB_MEMSTAGE_H__
|
9 |
|
|
#define __DEBUGGER_RIVERLIB_MEMSTAGE_H__
|
10 |
|
|
|
11 |
|
|
#include <systemc.h>
|
12 |
|
|
#include "../river_cfg.h"
|
13 |
|
|
|
14 |
|
|
namespace debugger {
|
15 |
|
|
|
16 |
|
|
SC_MODULE(MemAccess) {
|
17 |
|
|
sc_in<bool> i_clk;
|
18 |
|
|
sc_in<bool> i_nrst;
|
19 |
|
|
sc_in<bool> i_e_valid; // Execution stage outputs are valid
|
20 |
|
|
sc_in<sc_uint<BUS_ADDR_WIDTH>> i_e_pc; // Execution stage instruction pointer
|
21 |
|
|
sc_in<sc_uint<32>> i_e_instr; // Execution stage instruction value
|
22 |
|
|
|
23 |
|
|
sc_in<sc_uint<5>> i_res_addr; // Register address to be written (0=no writing)
|
24 |
|
|
sc_in<sc_uint<RISCV_ARCH>> i_res_data; // Register value to be written
|
25 |
|
|
sc_in<bool> i_memop_sign_ext; // Load data with sign extending (if less than 8 Bytes)
|
26 |
|
|
sc_in<bool> i_memop_load; // Load data from memory and write to i_res_addr
|
27 |
|
|
sc_in<bool> i_memop_store; // Store i_res_data value into memory
|
28 |
|
|
sc_in<sc_uint<2>> i_memop_size; // Encoded memory transaction size in bytes: 0=1B; 1=2B; 2=4B; 3=8B
|
29 |
|
|
sc_in<sc_uint<BUS_ADDR_WIDTH>> i_memop_addr; // Memory access address
|
30 |
|
|
sc_out<bool> o_wena; // Write enable signal
|
31 |
|
|
sc_out<sc_uint<5>> o_waddr; // Output register address (0 = x0 = no write)
|
32 |
|
|
sc_out<sc_uint<RISCV_ARCH>> o_wdata; // Register value
|
33 |
|
|
|
34 |
|
|
// Memory interface:
|
35 |
|
|
sc_in<bool> i_mem_req_ready; // Data cache is ready to accept request
|
36 |
|
|
sc_out<bool> o_mem_valid; // Memory request is valid
|
37 |
|
|
sc_out<bool> o_mem_write; // Memory write request
|
38 |
|
|
sc_out<sc_uint<2>> o_mem_sz; // Encoded data size in bytes: 0=1B; 1=2B; 2=4B; 3=8B
|
39 |
|
|
sc_out<sc_uint<BUS_ADDR_WIDTH>> o_mem_addr; // Data path requested address
|
40 |
|
|
sc_out<sc_uint<BUS_DATA_WIDTH>> o_mem_data; // Data path requested data (write transaction)
|
41 |
|
|
sc_in<bool> i_mem_data_valid; // Data path memory response is valid
|
42 |
|
|
sc_in<sc_uint<BUS_ADDR_WIDTH>> i_mem_data_addr; // Data path memory response address
|
43 |
|
|
sc_in<sc_uint<BUS_DATA_WIDTH>> i_mem_data; // Data path memory response value
|
44 |
|
|
sc_out<bool> o_mem_resp_ready; // Pipeline is ready to accept memory operation response
|
45 |
|
|
|
46 |
|
|
sc_out<bool> o_hold; // Hold pipeline by data cache wait state reason
|
47 |
|
|
sc_out<bool> o_valid; // Output is valid
|
48 |
|
|
sc_out<sc_uint<BUS_ADDR_WIDTH>> o_pc; // Valid instruction pointer
|
49 |
|
|
sc_out<sc_uint<32>> o_instr; // Valid instruction value
|
50 |
|
|
|
51 |
|
|
void comb();
|
52 |
|
|
void registers();
|
53 |
|
|
|
54 |
|
|
SC_HAS_PROCESS(MemAccess);
|
55 |
|
|
|
56 |
|
|
MemAccess(sc_module_name name_);
|
57 |
|
|
|
58 |
|
|
void generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd);
|
59 |
|
|
|
60 |
|
|
private:
|
61 |
|
|
struct RegistersType {
|
62 |
|
|
sc_signal<bool> valid;
|
63 |
|
|
sc_signal<sc_uint<BUS_ADDR_WIDTH>> pc;
|
64 |
|
|
sc_signal<sc_uint<32>> instr;
|
65 |
|
|
|
66 |
|
|
sc_signal<bool> wena;
|
67 |
|
|
sc_signal<sc_uint<5>> waddr;
|
68 |
|
|
sc_signal<bool> sign_ext;
|
69 |
|
|
sc_signal<sc_uint<2>> size;
|
70 |
|
|
sc_signal<sc_uint<RISCV_ARCH>> wdata;
|
71 |
|
|
sc_signal<bool> wait_req;
|
72 |
|
|
sc_signal<bool> wait_req_write;
|
73 |
|
|
sc_signal<sc_uint<2>> wait_req_sz;
|
74 |
|
|
sc_signal<sc_uint<BUS_ADDR_WIDTH>> wait_req_addr;
|
75 |
|
|
sc_signal<sc_uint<RISCV_ARCH>> wait_req_wdata;
|
76 |
|
|
sc_signal<bool> wait_resp;
|
77 |
|
|
} v, r;
|
78 |
|
|
};
|
79 |
|
|
|
80 |
|
|
|
81 |
|
|
} // namespace debugger
|
82 |
|
|
|
83 |
|
|
#endif // __DEBUGGER_RIVERLIB_EXECUTE_H__
|