Skip to content

Commit

Permalink
[rtl] Add FPGA Register File
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
ganoam authored and vogelpi committed Jan 14, 2020
1 parent 0c55214 commit 7969cb7
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 2 deletions.
13 changes: 12 additions & 1 deletion doc/register_file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------------------

Expand Down
3 changes: 2 additions & 1 deletion ibex_core.core
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 3 additions & 0 deletions lint/verilator_waiver.vlt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
57 changes: 57 additions & 0 deletions rtl/ibex_register_file_fpga.sv
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 7969cb7

Please sign in to comment.