mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-19 03:44:46 -04:00
using verible-v0.0-3422-g520ca4b9/bin/verible-verilog-format with default configuration Note: two files are not correctly handled by verible - core/include/std_cache_pkg.sv - core/cache_subsystem/cva6_hpdcache_if_adapter.sv
114 lines
4.4 KiB
Systemverilog
114 lines
4.4 KiB
Systemverilog
// Copyright 2018 ETH Zurich and University of Bologna.
|
|
// Copyright and related rights are licensed under the Solderpad Hardware
|
|
// License, Version 0.51 (the "License"); you may not use this file except in
|
|
// compliance with the License. You may obtain a copy of the License at
|
|
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
|
// or agreed to in writing, software, hardware and materials distributed under
|
|
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations under the License.
|
|
//
|
|
// Author: Antonio Pullini - pullinia@iis.ee.ethz.ch
|
|
//
|
|
// Additional contributions by:
|
|
// Sven Stucki - svstucki@student.ethz.ch
|
|
// Markus Wegmann - markus.wegmann@technokrat.ch
|
|
//
|
|
// Design Name: RISC-V register file
|
|
// Project Name: zero-riscy
|
|
// Language: SystemVerilog
|
|
//
|
|
// Description: Register file with 31 or 15x 32 bit wide registers.
|
|
// Register 0 is fixed to 0. This register file is based on
|
|
// latches and is thus smaller than the flip-flop based RF.
|
|
//
|
|
|
|
module ariane_regfile_lol #(
|
|
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
|
parameter int unsigned DATA_WIDTH = 32,
|
|
parameter int unsigned NR_READ_PORTS = 2,
|
|
parameter bit ZERO_REG_ZERO = 0
|
|
) (
|
|
// clock and reset
|
|
input logic clk_i,
|
|
input logic rst_ni,
|
|
// disable clock gates for testing
|
|
input logic test_en_i,
|
|
// read port
|
|
input logic [ NR_READ_PORTS-1:0][ 4:0] raddr_i,
|
|
output logic [ NR_READ_PORTS-1:0][DATA_WIDTH-1:0] rdata_o,
|
|
// write port
|
|
input logic [CVA6Cfg.NrCommitPorts-1:0][ 4:0] waddr_i,
|
|
input logic [CVA6Cfg.NrCommitPorts-1:0][DATA_WIDTH-1:0] wdata_i,
|
|
input logic [CVA6Cfg.NrCommitPorts-1:0] we_i
|
|
);
|
|
|
|
localparam ADDR_WIDTH = 5;
|
|
localparam NUM_WORDS = 2 ** ADDR_WIDTH;
|
|
|
|
logic [NUM_WORDS-1:ZERO_REG_ZERO] mem_clocks;
|
|
|
|
logic [ DATA_WIDTH-1:0] mem [NUM_WORDS];
|
|
logic [CVA6Cfg.NrCommitPorts-1:0][NUM_WORDS-1:1] waddr_onehot, waddr_onehot_q;
|
|
logic [CVA6Cfg.NrCommitPorts-1:0][DATA_WIDTH-1:0] wdata_q;
|
|
|
|
|
|
// decode addresses
|
|
for (genvar i = 0; i < NR_READ_PORTS; i++) assign rdata_o[i] = mem[raddr_i[i][ADDR_WIDTH-1:0]];
|
|
|
|
always_ff @(posedge clk_i, negedge rst_ni) begin : sample_waddr
|
|
if (~rst_ni) begin
|
|
wdata_q <= '0;
|
|
end else begin
|
|
for (int unsigned i = 0; i < CVA6Cfg.NrCommitPorts; i++)
|
|
// enable flipflop will most probably infer clock gating
|
|
if (we_i[i]) begin
|
|
wdata_q[i] <= wdata_i[i];
|
|
end
|
|
waddr_onehot_q <= waddr_onehot;
|
|
end
|
|
end
|
|
|
|
// WRITE : Write Address Decoder (WAD), combinatorial process
|
|
always_comb begin : decode_write_addess
|
|
for (int unsigned i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
|
|
for (int unsigned j = 1; j < NUM_WORDS; j++) begin
|
|
if (we_i[i] && (waddr_i[i] == j)) waddr_onehot[i][j] = 1'b1;
|
|
else waddr_onehot[i][j] = 1'b0;
|
|
end
|
|
end
|
|
end
|
|
|
|
// WRITE : Clock gating (if integrated clock-gating cells are available)
|
|
for (genvar x = ZERO_REG_ZERO; x < NUM_WORDS; x++) begin
|
|
|
|
logic [CVA6Cfg.NrCommitPorts-1:0] waddr_ored;
|
|
|
|
for (genvar i = 0; i < CVA6Cfg.NrCommitPorts; i++) assign waddr_ored[i] = waddr_onehot[i][x];
|
|
|
|
cluster_clock_gating i_cg (
|
|
.clk_i (clk_i),
|
|
.en_i (|waddr_ored),
|
|
.test_en_i(test_en_i),
|
|
.clk_o (mem_clocks[x])
|
|
);
|
|
end
|
|
|
|
// Generate M = WORDS sequential processes, each of which describes one
|
|
// word of the memory. The processes are synchronized with the clocks
|
|
// ClocksxC(i), i = 0, 1, ..., M-1
|
|
// Use active low, i.e. transparent on low latches as storage elements
|
|
// Data is sampled on rising clock edge
|
|
|
|
// Integer registers
|
|
always_latch begin : latch_wdata
|
|
// Note: The assignment has to be done inside this process or Modelsim complains about it
|
|
if (ZERO_REG_ZERO) mem[0] = '0;
|
|
|
|
for (int unsigned i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
|
|
for (int unsigned k = ZERO_REG_ZERO; k < NUM_WORDS; k++) begin
|
|
if (mem_clocks[k] && waddr_onehot_q[i][k]) mem[k] = wdata_q[i];
|
|
end
|
|
end
|
|
end
|
|
endmodule
|