mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-22 13:07:46 -04:00
[rtl] Add FPGA Register File
This commit adds a register file designed to be synthesized into FPGA synchronous-write / asynchronous-read design elements. For the artya7-100 example, the register file is implemented by 12 RAM32M primitives, conserving approximately 600 Logic LUTs and 1000 flip-flops at the expense of 48 LUTRAMs. Signed-off-by: ganoam <gnoam@live.com>
This commit is contained in:
parent
0c55214380
commit
7969cb722b
4 changed files with 74 additions and 2 deletions
|
@ -17,10 +17,21 @@ Flip-Flop-Based Register File
|
|||
|
||||
The flip-flop-based register file uses regular, positive-edge-triggered flip-flops to implement the registers.
|
||||
|
||||
This makes it the **first choice for FPGA synthesis** or when simulating the design using Verilator.
|
||||
This makes it the **first choice when simulating the design using Verilator**.
|
||||
|
||||
To select the flip-flop-based register file, make sure to use the source file ``ibex_register_file_ff.sv`` in your project.
|
||||
|
||||
FPGA Register File
|
||||
--------------------------
|
||||
|
||||
The FPGA register file leverages synchronous-write / asynchronous-read RAM design elements, where available on FPGA targets.
|
||||
|
||||
For Xilinx FPGAs, synthesis results in an implementation using RAM32M primitives. Using this design with a Xilinx Artya7-100 FPGA conserves around 600 Logic LUTs and 1000 flip-flops at the expense of 48 LUTRAMs for the 31-entry register file as compared to the flip-flop-based register file.
|
||||
|
||||
This makes it the **first choice for FPGA synthesis**.
|
||||
|
||||
To select the FPGA register file, make sure to use the source file ``ibex_register_file_fpga.sv`` in your project.
|
||||
|
||||
Latch-Based Register File
|
||||
-------------------------
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@ filesets:
|
|||
# XXX: Figure out the best way to switch these two implementations
|
||||
# dynamically on the target.
|
||||
# - rtl/ibex_register_file_latch.sv # ASIC
|
||||
- rtl/ibex_register_file_ff.sv # FPGA
|
||||
# - rtl/ibex_register_file_fpga.sv # FPGA
|
||||
- rtl/ibex_register_file_ff.sv # generic FF-based
|
||||
- rtl/ibex_core.sv
|
||||
file_type: systemVerilogSource
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ lint_off -msg PINCONNECTEMPTY
|
|||
// implementation choices for the same module.
|
||||
lint_off -msg DECLFILENAME -file "*/rtl/ibex_register_file_ff.sv"
|
||||
lint_off -msg DECLFILENAME -file "*/rtl/ibex_register_file_latch.sv"
|
||||
lint_off -msg DECLFILENAME -file "*/rtl/ibex_register_file_fpga.sv"
|
||||
|
||||
// Bits of signal are not used: boot_addr_i[7:0]
|
||||
// Boot address is 256B aligned, cleaner to pass all bits in
|
||||
|
@ -45,6 +46,7 @@ lint_off -msg UNUSED -file "*/rtl/ibex_multdiv_fast.sv" -lines 68
|
|||
// Signal is not used: test_en_i
|
||||
// testability signal
|
||||
lint_off -msg UNUSED -file "*/rtl/ibex_register_file_ff.sv" -lines 21
|
||||
lint_off -msg UNUSED -file "*/rtl/ibex_register_file_fpga.sv" -lines 22
|
||||
|
||||
// Signal is not used: clk_i
|
||||
// leaving clk and reset connected in-case we want to add assertions
|
||||
|
@ -57,6 +59,7 @@ lint_off -msg UNUSED -file "*/rtl/ibex_decoder.sv" -lines 21
|
|||
lint_off -msg UNUSED -file "*/rtl/ibex_pmp.sv" -lines 16
|
||||
lint_off -msg UNUSED -file "*/rtl/ibex_compressed_decoder.sv" -lines 15
|
||||
lint_off -msg UNUSED -file "*/rtl/ibex_decoder.sv" -lines 22
|
||||
lint_off -msg UNUSED -file "*/rtl/ibex_register_file_fpga.sv" -lines 20
|
||||
|
||||
// Signal unoptimizable: Feedback to clock or circular logic:
|
||||
// ibex_core.cs_registers_i.mie_q
|
||||
|
|
57
rtl/ibex_register_file_fpga.sv
Normal file
57
rtl/ibex_register_file_fpga.sv
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Copyright 2018 ETH Zurich and University of Bologna, see also CREDITS.md.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/**
|
||||
* RISC-V register file
|
||||
*
|
||||
* Register file with 31 or 15x 32 bit wide registers. Register 0 is fixed to 0.
|
||||
*
|
||||
* This register file is designed to make FPGA synthesis tools infer RAM primitives. For Xilinx
|
||||
* FPGA architectures, it will produce RAM32M primitives. Other vendors have not yet been tested.
|
||||
*/
|
||||
module ibex_register_file #(
|
||||
parameter bit RV32E = 0,
|
||||
parameter int unsigned DataWidth = 32
|
||||
) (
|
||||
// Clock and Reset
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
||||
input logic test_en_i,
|
||||
|
||||
//Read port R1
|
||||
input logic [ 4:0] raddr_a_i,
|
||||
output logic [DataWidth-1:0] rdata_a_o,
|
||||
//Read port R2
|
||||
input logic [ 4:0] raddr_b_i,
|
||||
output logic [DataWidth-1:0] rdata_b_o,
|
||||
// Write port W1
|
||||
input logic [ 4:0] waddr_a_i,
|
||||
input logic [DataWidth-1:0] wdata_a_i,
|
||||
input logic we_a_i
|
||||
);
|
||||
|
||||
localparam int ADDR_WIDTH = RV32E ? 4 : 5;
|
||||
localparam int NUM_WORDS = 2**ADDR_WIDTH;
|
||||
|
||||
logic [DataWidth-1:0] mem[NUM_WORDS];
|
||||
logic we; // write enable if writing to any register other than R0
|
||||
|
||||
// async_read a
|
||||
assign rdata_a_o = (raddr_a_i == '0) ? '0 : mem[raddr_a_i];
|
||||
|
||||
// async_read b
|
||||
assign rdata_b_o = (raddr_b_i == '0) ? '0 : mem[baddr_b_i];
|
||||
|
||||
// we select
|
||||
assign we = (waddr_a_i == '0) ? 1'b0 : we_a_i;
|
||||
|
||||
always_ff @(posedge clk_i) begin : sync_write
|
||||
if (we == 1'b1) begin
|
||||
mem[waddr_a_i] <= wdata_a_i;
|
||||
end
|
||||
end : sync_write
|
||||
|
||||
endmodule : ibex_register_file
|
Loading…
Add table
Add a link
Reference in a new issue