Added support for dual-port register file
This commit is contained in:
parent
60867e10a9
commit
34d9dea8c7
69
README.md
69
README.md
|
@ -43,30 +43,65 @@ memory-mapped peripherals, communicating with each other using the native
|
||||||
interface, and communicating with the outside world via AXI4.
|
interface, and communicating with the outside world via AXI4.
|
||||||
|
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The following Verilog module parameters can be used to configure the PicoRV32
|
||||||
|
core.
|
||||||
|
|
||||||
|
### ENABLE_COUNTERS (default = 1)
|
||||||
|
|
||||||
|
This parameter enables support for the `RDCYCLE[H]`, `RDTIME[H]`, and
|
||||||
|
`RDINSTRET[H]` instructions. This instructions will cause a hardware
|
||||||
|
trap (like any other unsupported instruction) if `ENABLE_COUNTERS` is set to zero.
|
||||||
|
|
||||||
|
*Note: Strictly speaking the `RDCYCLE[H]`, `RDTIME[H]`, and `RDINSTRET[H]`
|
||||||
|
instructions are not optional for an RV32I core. But chances are they are not
|
||||||
|
going to be missed after the application code has been debugged and profiled.
|
||||||
|
This instructions are optional for an RV32E core.*
|
||||||
|
|
||||||
|
### ENABLE_REGS_16_31 (default = 1)
|
||||||
|
|
||||||
|
This parameter enables support for registers the `x16`..`x31`. The RV32E ISA
|
||||||
|
excludes this registers. However, the RV32E ISA spec requires a hardware trap
|
||||||
|
for when code tries to access this registers. This is not implemented in PicoRV32.
|
||||||
|
|
||||||
|
### ENABLE_REGS_DUALPORT (default = 1)
|
||||||
|
|
||||||
|
The register file can be implemented with two or one read ports. A dual ported
|
||||||
|
register file improves performance a bit, but can also increase the size of
|
||||||
|
the core.
|
||||||
|
|
||||||
|
|
||||||
Performance:
|
Performance:
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The average Cycles per Instruction (CPI) is 4 to 6, depending on the mix of
|
*A short reminder: This core is optimized for size, not performance.*
|
||||||
instructions in the code. The CPI numbers for the individual instructions are:
|
|
||||||
|
|
||||||
| Instruction | CPI |
|
Unless stated otherwise, the following numbers apply to a PicoRV32 with
|
||||||
| ---------------------| ----:|
|
ENABLE_REGS_DUALPORT active and connected to a memory that can accomodate
|
||||||
| direct jump (jal) | 3 |
|
requests within one clock cycle.
|
||||||
| ALU reg + immediate | 3 |
|
|
||||||
| ALU reg + reg | 4 |
|
|
||||||
| branch (not taken) | 4 |
|
|
||||||
| memory load | 5 |
|
|
||||||
| memory store | 6 |
|
|
||||||
| branch (taken) | 6 |
|
|
||||||
| indirect jump (jalr) | 6 |
|
|
||||||
| shift operations | 4-15 |
|
|
||||||
|
|
||||||
Dhrystone benchmark results: 0.280 DMIPS/MHz (493 Dhrystones/Second/MHz)
|
The average Cycles per Instruction (CPI) is 4 to 5, depending on the mix of
|
||||||
|
instructions in the code. The CPI numbers for the individual instructions
|
||||||
|
can be found in the following table. (The column "CPI (SP)" contains the
|
||||||
|
CPI numbers for a core built without ENABLE_REGS_DUALPORT.)
|
||||||
|
|
||||||
For the Dryhstone benchmark the average CPI is 4.606.
|
| Instruction | CPI | CPI (SP) |
|
||||||
|
| ---------------------| ----:| --------:|
|
||||||
|
| direct jump (jal) | 3 | 3 |
|
||||||
|
| ALU reg + immediate | 3 | 3 |
|
||||||
|
| ALU reg + reg | 3 | 4 |
|
||||||
|
| branch (not taken) | 3 | 4 |
|
||||||
|
| memory load | 5 | 5 |
|
||||||
|
| memory store | 5 | 6 |
|
||||||
|
| branch (taken) | 5 | 6 |
|
||||||
|
| indirect jump (jalr) | 6 | 6 |
|
||||||
|
| shift operations | 4-14 | 4-15 |
|
||||||
|
|
||||||
*This numbers apply to systems with memory that can accomodate requests within
|
Dhrystone benchmark results: 0.309 DMIPS/MHz (544 Dhrystones/Second/MHz)
|
||||||
one clock cycle. Slower memory will degrade the performance of the processor.*
|
|
||||||
|
For the Dryhstone benchmark the average CPI is 4.167.
|
||||||
|
|
||||||
|
|
||||||
Todos:
|
Todos:
|
||||||
|
|
26
picorv32.v
26
picorv32.v
|
@ -27,7 +27,8 @@
|
||||||
|
|
||||||
module picorv32 #(
|
module picorv32 #(
|
||||||
parameter ENABLE_COUNTERS = 1,
|
parameter ENABLE_COUNTERS = 1,
|
||||||
parameter ENABLE_REGS_16_31 = 1
|
parameter ENABLE_REGS_16_31 = 1,
|
||||||
|
parameter ENABLE_REGS_DUALPORT = 1
|
||||||
) (
|
) (
|
||||||
input clk, resetn,
|
input clk, resetn,
|
||||||
output reg trap,
|
output reg trap,
|
||||||
|
@ -529,6 +530,21 @@ module picorv32 #(
|
||||||
reg_op2 <= decoded_imm;
|
reg_op2 <= decoded_imm;
|
||||||
mem_do_rinst <= mem_do_prefetch;
|
mem_do_rinst <= mem_do_prefetch;
|
||||||
cpu_state <= cpu_state_exec;
|
cpu_state <= cpu_state_exec;
|
||||||
|
end else if (ENABLE_REGS_DUALPORT) begin
|
||||||
|
`ifdef DEBUG
|
||||||
|
$display("LD_RS2: %2d 0x%08x", decoded_rs2, decoded_rs2 ? cpuregs[decoded_rs2] : 0);
|
||||||
|
`endif
|
||||||
|
reg_op2 <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
|
if (is_sb_sh_sw) begin
|
||||||
|
cpu_state <= cpu_state_stmem;
|
||||||
|
mem_do_rinst <= 1;
|
||||||
|
end else if (is_sll_srl_sra) begin
|
||||||
|
reg_sh <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
|
cpu_state <= cpu_state_shift;
|
||||||
|
end else begin
|
||||||
|
mem_do_rinst <= mem_do_prefetch;
|
||||||
|
cpu_state <= cpu_state_exec;
|
||||||
|
end
|
||||||
end else
|
end else
|
||||||
cpu_state <= cpu_state_ld_rs2;
|
cpu_state <= cpu_state_ld_rs2;
|
||||||
end
|
end
|
||||||
|
@ -689,7 +705,8 @@ endmodule
|
||||||
|
|
||||||
module picorv32_axi #(
|
module picorv32_axi #(
|
||||||
parameter ENABLE_COUNTERS = 1,
|
parameter ENABLE_COUNTERS = 1,
|
||||||
parameter ENABLE_REGS_16_31 = 1
|
parameter ENABLE_REGS_16_31 = 1,
|
||||||
|
parameter ENABLE_REGS_DUALPORT = 1
|
||||||
) (
|
) (
|
||||||
input clk, resetn,
|
input clk, resetn,
|
||||||
output trap,
|
output trap,
|
||||||
|
@ -756,8 +773,9 @@ module picorv32_axi #(
|
||||||
);
|
);
|
||||||
|
|
||||||
picorv32 #(
|
picorv32 #(
|
||||||
.ENABLE_COUNTERS (ENABLE_COUNTERS ),
|
.ENABLE_COUNTERS (ENABLE_COUNTERS ),
|
||||||
.ENABLE_REGS_16_31(ENABLE_REGS_16_31)
|
.ENABLE_REGS_16_31 (ENABLE_REGS_16_31 ),
|
||||||
|
.ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT)
|
||||||
) picorv32_core (
|
) picorv32_core (
|
||||||
.clk (clk ),
|
.clk (clk ),
|
||||||
.resetn (resetn ),
|
.resetn (resetn ),
|
||||||
|
|
Loading…
Reference in New Issue