| .. _register-file: |
| |
| Register File |
| ============= |
| |
| Ibex has either 31 or 15 32-bit registers if the RV32E extension is disabled or enabled, respectively. |
| Register ``x0`` is statically bound to 0 and can only be read, it does not contain any sequential logic. |
| |
| There are two flavors of register file available, both having their own benefits and trade-offs. |
| |
| 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. |
| |
| To select the flip-flop-based register file, make sure to use the source file ``ibex_register_file_ff.sv`` in your project. |
| |
| Latch-Based Register File |
| ------------------------- |
| |
| The latch-based register file uses level-sensitive latches to implement the registers. |
| |
| This allows for significant area savings compared to an implementation using regular flip-flops and thus makes the latch-based register file the **first choice for ASIC implementations**. |
| Simulation of the latch-based register file is possible using commercial tools. |
| |
| .. note:: The latch-based register file cannot be simulated using Verilator. |
| |
| The latch-based register file can also be used for FPGA synthesis, but this is not recommended as FPGAs usually do not well support latches. |
| |
| To select the latch-based register file, make sure to use the source file ``ibex_register_file_latch.sv`` in your project. |
| In addition, a technology-specific clock gating cell must be provided to keep the clock inactive when the latches are not written. |
| This cell must be wrapped in a module called ``prim_clock_gating``. |
| For more information regarding the clock gating cell, checkout :ref:`getting-started`. |
| |
| .. note:: The latch-based register file requires the gated clock to be enabled in the cycle after the write enable ``we_a_i`` signal was set high. |
| This can be achieved by latching ``we_a_i`` in the clock gating cell during the low phase of ``clk_i``. |
| |
| The resulting behavior of the latch-based register file is visualized in :numref:`timing`. |
| The input data ``wdata_a_i`` is sampled into a flip-flop-based register ``wdata_a_q`` using ``clk_int``. |
| The actual latch-based registers ``mem[1]`` and ``mem[2]`` are transparent during high phases of ``mem_clk[1]`` and ``mem_clk[2]``, respectively. |
| Their content is sampled from ``wdata_a_q`` on falling edges of these clocks. |
| |
| .. wavedrom:: |
| :name: timing |
| :caption: Latch-based register file operation |
| |
| {"signal": |
| [ |
| {"name": "clk_i", "wave": "hlhlhlhl"}, |
| {"name": "we_a_i", "wave": "0.1...0."}, |
| {"name": "waddr_a_i", "wave": "xx=.=.xx", "data": ["1","2"]}, |
| {"name": "wdata_a_i", "wave": "xx=.=.xx", "data": ["Data1","Data2"]}, |
| {"name": "clk_int", "wave": "0...HlHl"}, |
| {"name": "wdata_a_q", "wave": "xxxx=.=.", "data": ["Data1", "Data2"]}, |
| {"name": "mem_clk[1]", "wave": "0...hL.."}, |
| {"name": "mem[1]", "wave": "xxxx=...", "data": ["Data1"]}, |
| {"name": "mem_clk[2]", "wave": "0.....hL"}, |
| {"name": "mem[2]", "wave": "xxxxxx=.", "data": ["Data2"]} |
| ], |
| "config": { "hscale": 2 } |
| } |