CDL Modules
riscv_i32c_pipeline3

Detailed Description

Modules

module riscv_i32c_pipeline3::riscv_i32c_pipeline3 ( clock  clk,
input bit  reset_n,
input t_riscv_irqs  irqs,
output t_riscv_mem_access_req  dmem_access_req,
input t_riscv_mem_access_resp  dmem_access_resp,
output t_riscv_fetch_req  ifetch_req,
input t_riscv_fetch_resp  ifetch_resp,
output t_riscv_i32_coproc_controls  coproc_controls,
input t_riscv_i32_coproc_response  coproc_response,
input t_riscv_config  riscv_config,
output t_riscv_i32_trace  trace 
)
Parameters
[in]irqsInterrupts in to the CPU
[out]traceThis is just the processor pipeline, using thress stages for execution.

The decode and RFR is performed in the first stage

The ALU execution (and coprocessor execution) is performed in the second stage

Memory operations are performed in the third stage

Register file is written at the end of the third stage; there is a RFW stage to forward data from RFW back to execution.

Instruction fetch

The instruction fetch request for the next cycle is put out just after the ALU stage logic, which may be a long time into the cycle (althought the design keeps this to a minimum); the fetch data response presents the instruction fetched at the end of the cycle, where it is registered for execution.

The instruction fetch response must then be valid combinatorially based on the instruction fetch request.

Data memory access

The data memory request is presented in the ALU stage, for an access to complete during the memory stage.

To support simple synchronous memory operation the data memory access includes valid write data in the same cycle as the request.

The data memory response is valid one cycle later than a request. This includes a wait signal. The external memory subsystem, therefore, is a two stage pipeline. The wait signal controls whether an access completes, but not if an access can be taken (except indirectly).

Hence external logic must always either register a request or guarantee not to assert wait.

An example implementation of could be dmem_access_resp.wait = fn ( access_in_progress ); access_can_be_taken = (!access_in_progress.valid) || (!dmem_access_resp.wait); if (access_can_be_taken) { access_in_progress <= dmem_access_req; } }