1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-17 20:02:53 +08:00
oh/stdlib/hdl/oh_regfile.v
aolofsson de63dfd907 Major reorg!
-stdcells moved to asiclib, doesn't make sense to be vectorized
-common is a stupid name, renamed as stdlib
2021-07-29 11:20:44 -04:00

77 lines
2.3 KiB
Verilog

//#############################################################################
//# Function: Parametrized register file #
//#############################################################################
//# Author: Andreas Olofsson #
//# License: MIT (see LICENSE file in OH! repository) #
//#############################################################################
module oh_regfile
# (parameter REGS = 8, // number of registeres
parameter RW = 16, // register width
parameter RP = 5, // read ports
parameter WP = 3, // write prots
parameter RAW = $clog2(REGS)// (derived) rf addr width
)
(//Control inputs
input clk,
// Write Ports (concatenated)
input [WP-1:0] wr_valid, // write access
input [WP*RAW-1:0] wr_addr, // register address
input [WP*RW-1:0] wr_data, // write data
// Read Ports (concatenated)
input [RP-1:0] rd_valid, // read access
input [RP*RAW-1:0] rd_addr, // register address
output [RP*RW-1:0] rd_data // output data
);
reg [RW-1:0] mem[0:REGS-1];
wire [WP-1:0] write_en [0:REGS-1];
wire [RW-1:0] datamux [0:REGS-1];
genvar i,j;
//TODO: Make an array of cells
//#########################################
// write ports
//#########################################
//One hote write enables
for(i=0;i<REGS;i=i+1)
begin: gen_regwrite
for(j=0;j<WP;j=j+1)
begin: gen_wp
assign write_en[i][j] = wr_valid[j] & (wr_addr[j*RAW+:RAW] == i);
end
end
//Multi Write-Port Mux
for(i=0;i<REGS;i=i+1)
begin: gen_wrmux
oh_mux #(.N(RW), .M(WP))
iwrmux(.out (datamux[i][RW-1:0]),
.sel (write_en[i][WP-1:0]),
.in (wr_data[WP*RW-1:0]));
end
//Memory Array Write
for(i=0;i<REGS;i=i+1)
begin: gen_reg
always @ (posedge clk)
if (|write_en[i][WP-1:0])
mem[i] <= datamux[i];
end
//#########################################
// read ports
//#########################################
for (i=0;i<RP;i=i+1) begin: gen_rdport
assign rd_data[i*RW+:RW] = {(RW){rd_valid[i]}} &
mem[rd_addr[i*RAW+:RAW]];
end
endmodule // oh_regfile