mirror of
https://github.com/olofk/serv.git
synced 2025-04-20 11:57:07 -04:00
Create RAM and RF IF with configurable widths
This commit is contained in:
parent
68d8af71f2
commit
31c138e4a1
6 changed files with 210 additions and 223 deletions
|
@ -1,87 +0,0 @@
|
|||
`default_nettype none
|
||||
module serv_regfile
|
||||
(
|
||||
input wire i_clk,
|
||||
input wire i_rst,
|
||||
input wire i_go,
|
||||
output reg o_ready,
|
||||
input wire i_rd_en,
|
||||
input wire [4:0] i_rd_addr,
|
||||
input wire i_rd,
|
||||
input wire [4:0] i_rs1_addr,
|
||||
input wire [4:0] i_rs2_addr,
|
||||
output wire o_rs1,
|
||||
output wire o_rs2);
|
||||
|
||||
reg t;
|
||||
always @(posedge i_clk) begin
|
||||
o_ready <= t;
|
||||
t <= i_go;
|
||||
if (i_rst) begin
|
||||
o_ready <= 1'b0;
|
||||
t <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
reg rd_r;
|
||||
|
||||
reg [1:0] rdata;
|
||||
reg [4:0] rcnt;
|
||||
reg [4:0] wcnt;
|
||||
reg rs1;
|
||||
reg rs2;
|
||||
reg rs1_r;
|
||||
|
||||
wire rs1_en = rcnt[0];
|
||||
wire rs1_tmp = (rs1_en ? rdata[0] : rs1);
|
||||
|
||||
wire [1:0] wdata = {i_rd, rd_r};
|
||||
always @(posedge i_clk) begin
|
||||
rd_r <= i_rd;
|
||||
if (i_rd_en)
|
||||
wcnt <= wcnt + 5'd1;
|
||||
|
||||
if (i_go)
|
||||
rcnt <= 5'd0;
|
||||
else
|
||||
rcnt <= rcnt + 4'd1;
|
||||
if (rs1_en) begin
|
||||
rs1 <= rdata[1];
|
||||
end else begin
|
||||
rs2 <= rdata[1];
|
||||
end
|
||||
rs1_r <= rs1_tmp;
|
||||
if (i_rst) begin
|
||||
wcnt <= 5'd0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
assign o_rs1 = rs1_r;
|
||||
assign o_rs2 = (rs1_en ? rs2 : rdata[0]);
|
||||
|
||||
wire [8:0] waddr = {i_rd_addr, wcnt[4:1]};
|
||||
wire wr_en = wcnt[0] & i_rd_en & (|i_rd_addr);
|
||||
|
||||
wire [8:0] raddr = {!rs1_en ? i_rs1_addr : i_rs2_addr, rcnt[4:1]};
|
||||
|
||||
reg [1:0] memory [0:511];
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (wr_en)
|
||||
memory[waddr] <= wdata;
|
||||
rdata <= memory[raddr];
|
||||
end
|
||||
|
||||
`ifdef RISCV_FORMAL
|
||||
`define SERV_CLEAR_RAM
|
||||
`endif
|
||||
|
||||
`ifdef SERV_CLEAR_RAM
|
||||
integer i;
|
||||
initial
|
||||
for (i=0;i<512;i=i+1)
|
||||
memory[i] = 2'd0;
|
||||
`endif
|
||||
|
||||
endmodule
|
|
@ -1,133 +0,0 @@
|
|||
`default_nettype none
|
||||
module serv_rf_2bit
|
||||
(
|
||||
input wire i_clk,
|
||||
input wire i_rst,
|
||||
input wire i_wreq,
|
||||
input wire i_rreq,
|
||||
output reg o_rgnt,
|
||||
input wire [5:0] i_wreg0,
|
||||
input wire [5:0] i_wreg1,
|
||||
input wire i_wen0,
|
||||
input wire i_wen1,
|
||||
input wire i_wdata0,
|
||||
input wire i_wdata1,
|
||||
input wire [5:0] i_rreg0,
|
||||
input wire [5:0] i_rreg1,
|
||||
output wire o_rdata0,
|
||||
output wire o_rdata1);
|
||||
|
||||
|
||||
/*
|
||||
********** Write side ***********
|
||||
*/
|
||||
|
||||
reg [4:0] wcnt;
|
||||
reg wgo;
|
||||
|
||||
wire [3:0] wslot = wcnt[4:1];
|
||||
wire wport = wcnt[0];
|
||||
|
||||
reg wdata0_r;
|
||||
reg wdata1_r;
|
||||
reg wdata1_2r;
|
||||
wire [1:0] wdata = !wport ?
|
||||
{i_wdata0, wdata0_r} :
|
||||
{wdata1_r, wdata1_2r};
|
||||
|
||||
wire [5:0] wreg = wport ? i_wreg1 : i_wreg0;
|
||||
wire [9:0] waddr = {wreg, wslot};
|
||||
|
||||
wire wen = wgo & (wport ? wen1_r : wen0_r);
|
||||
|
||||
reg wreq_r;
|
||||
|
||||
reg wen0_r;
|
||||
reg wen1_r;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
wen0_r <= i_wen0;
|
||||
wen1_r <= i_wen1;
|
||||
wreq_r <= i_wreq;
|
||||
wdata0_r <= i_wdata0;
|
||||
wdata1_r <= i_wdata1;
|
||||
wdata1_2r <= wdata1_r;
|
||||
|
||||
if (wgo)
|
||||
wcnt <= wcnt+5'd1;
|
||||
|
||||
if (wreq_r)
|
||||
wgo <= 1'b1;
|
||||
if (wcnt == 5'b11111)
|
||||
wgo <= 1'b0;
|
||||
|
||||
if (i_rst) begin
|
||||
wcnt <= 5'd0;
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
********** Read side ***********
|
||||
*/
|
||||
|
||||
|
||||
reg [4:0] rcnt;
|
||||
wire [3:0] rslot = rcnt[4:1];
|
||||
wire rport = rcnt[0];
|
||||
|
||||
wire [5:0] rreg = rport ? i_rreg1 : i_rreg0;
|
||||
wire [9:0] raddr = {rreg, rslot};
|
||||
|
||||
reg [1:0] rdata;
|
||||
reg [1:0] rdata0;
|
||||
reg rdata1;
|
||||
|
||||
|
||||
assign o_rdata0 = !rport ? rdata0[0] : rdata0[1];
|
||||
assign o_rdata1 = rport ? rdata1 : rdata[0];
|
||||
|
||||
reg rreq_r;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
rcnt <= rcnt+5'd1;
|
||||
if (i_rreq)
|
||||
rcnt <= 5'd0;
|
||||
|
||||
rreq_r <= i_rreq;
|
||||
o_rgnt <= rreq_r;
|
||||
|
||||
if (rport)
|
||||
rdata0 <= rdata;
|
||||
if (!rport)
|
||||
rdata1 <= rdata[1];
|
||||
|
||||
if (i_rst) begin
|
||||
o_rgnt <= 1'b0;
|
||||
rreq_r <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
reg [1:0] memory [0:575];
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (wen)
|
||||
`ifdef RISCV_FORMAL
|
||||
if (!i_rst)
|
||||
`endif
|
||||
memory[waddr] <= wdata;
|
||||
rdata <= memory[raddr];
|
||||
end
|
||||
|
||||
`ifdef RISCV_FORMAL
|
||||
`define SERV_CLEAR_RAM
|
||||
`endif
|
||||
|
||||
`ifdef SERV_CLEAR_RAM
|
||||
integer i;
|
||||
initial
|
||||
for (i=0;i<512;i=i+1)
|
||||
memory[i] = 2'd0;
|
||||
`endif
|
||||
|
||||
endmodule
|
25
rtl/serv_rf_ram.v
Normal file
25
rtl/serv_rf_ram.v
Normal file
|
@ -0,0 +1,25 @@
|
|||
module serv_rf_ram
|
||||
#(parameter width=0,
|
||||
parameter depth=32*36/width)
|
||||
(input wire i_clk,
|
||||
input wire [$clog2(depth)-1:0] i_waddr,
|
||||
input wire [width-1:0] i_wdata,
|
||||
input wire i_wen,
|
||||
input wire [$clog2(depth)-1:0] i_raddr,
|
||||
output reg [width-1:0] o_rdata);
|
||||
|
||||
reg [width-1:0] memory [0:depth-1];
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_wen)
|
||||
memory[i_waddr] <= i_wdata;
|
||||
o_rdata <= memory[i_raddr];
|
||||
end
|
||||
|
||||
`ifdef SERV_CLEAR_RAM
|
||||
integer i;
|
||||
initial
|
||||
for (i=0;i<depth;i=i+1)
|
||||
memory[i] = {width{1'd0}};
|
||||
`endif
|
||||
endmodule
|
160
rtl/serv_rf_ram_if.v
Normal file
160
rtl/serv_rf_ram_if.v
Normal file
|
@ -0,0 +1,160 @@
|
|||
`default_nettype none
|
||||
module serv_rf_ram_if
|
||||
#(parameter width=8,
|
||||
parameter depth=32*36/width)
|
||||
(
|
||||
//SERV side
|
||||
input wire i_clk,
|
||||
input wire i_rst,
|
||||
input wire i_wreq,
|
||||
input wire i_rreq,
|
||||
output reg o_rgnt,
|
||||
input wire [5:0] i_wreg0,
|
||||
input wire [5:0] i_wreg1,
|
||||
input wire i_wen0,
|
||||
input wire i_wen1,
|
||||
input wire i_wdata0,
|
||||
input wire i_wdata1,
|
||||
input wire [5:0] i_rreg0,
|
||||
input wire [5:0] i_rreg1,
|
||||
output wire o_rdata0,
|
||||
output wire o_rdata1,
|
||||
//RAM side
|
||||
output wire [$clog2(depth)-1:0] o_waddr,
|
||||
output wire [width-1:0] o_wdata,
|
||||
output wire o_wen,
|
||||
output wire [$clog2(depth)-1:0] o_raddr,
|
||||
input wire [width-1:0] i_rdata);
|
||||
|
||||
localparam l2w = $clog2(width);
|
||||
|
||||
/*
|
||||
********** Write side ***********
|
||||
*/
|
||||
|
||||
reg [4:0] wcnt;
|
||||
reg wgo;
|
||||
|
||||
|
||||
reg [width-2:0] wdata0_r;
|
||||
reg [width-1:0] wdata1_r;
|
||||
|
||||
reg wen0_r;
|
||||
reg wen1_r;
|
||||
wire wtrig0;
|
||||
wire wtrig1;
|
||||
|
||||
generate if (width == 2) begin
|
||||
assign wtrig0 = ~wcnt[0];
|
||||
assign wtrig1 = wcnt[0];
|
||||
end else begin
|
||||
reg wtrig0_r;
|
||||
always @(posedge i_clk) wtrig0_r <= wtrig0;
|
||||
assign wtrig0 = (wcnt[l2w-1:0] == {{l2w-1{1'b1}},1'b0});
|
||||
assign wtrig1 = wtrig0_r;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign o_wdata = wtrig1 ?
|
||||
wdata1_r :
|
||||
{i_wdata0, wdata0_r};
|
||||
|
||||
wire [5:0] wreg = wtrig1 ? i_wreg1 : i_wreg0;
|
||||
generate if (width == 32)
|
||||
assign o_waddr = wreg;
|
||||
else
|
||||
assign o_waddr = {wreg, wcnt[4:l2w]};
|
||||
endgenerate
|
||||
|
||||
assign o_wen = wgo & ((wtrig0 & wen0_r) | (wtrig1 & wen1_r));
|
||||
|
||||
reg wreq_r;
|
||||
reg wreq_edge;
|
||||
|
||||
generate if (width > 2)
|
||||
always @(posedge i_clk) wdata0_r <= {i_wdata0, wdata0_r[width-2:1]};
|
||||
else
|
||||
always @(posedge i_clk) wdata0_r <= i_wdata0;
|
||||
endgenerate
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
wen0_r <= i_wen0;
|
||||
wen1_r <= i_wen1;
|
||||
wreq_r <= i_wreq;
|
||||
wreq_edge <= i_wreq & !wreq_r;
|
||||
|
||||
wdata1_r <= {i_wdata1,wdata1_r[width-1:1]};
|
||||
|
||||
if (wgo)
|
||||
wcnt <= wcnt+5'd1;
|
||||
|
||||
if (wreq_r) begin
|
||||
wgo <= 1'b1;
|
||||
end
|
||||
|
||||
if (wcnt == 5'b11111)
|
||||
wgo <= 1'b0;
|
||||
|
||||
if (i_rst) begin
|
||||
wcnt <= 5'd0;
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
********** Read side ***********
|
||||
*/
|
||||
|
||||
reg [4:0] rcnt;
|
||||
|
||||
wire rtrig0;
|
||||
reg rtrig1;
|
||||
|
||||
wire [5:0] rreg = rtrig0 ? i_rreg1 : i_rreg0;
|
||||
generate if (width == 32)
|
||||
assign o_raddr = rreg;
|
||||
else
|
||||
assign o_raddr = {rreg, rcnt[4:l2w]};
|
||||
endgenerate
|
||||
|
||||
reg [width-1:0] rdata0;
|
||||
reg [width-2:0] rdata1;
|
||||
|
||||
assign o_rdata0 = rdata0[0];
|
||||
assign o_rdata1 = rtrig1 ? i_rdata[0] : rdata1[0];
|
||||
|
||||
assign rtrig0 = (rcnt[l2w-1:0] == 1);
|
||||
|
||||
reg rreq_r;
|
||||
|
||||
generate if (width>2)
|
||||
always @(posedge i_clk) begin
|
||||
rdata1 <= {1'b0,rdata1[width-2:1]}; //Optimize?
|
||||
if (rtrig1)
|
||||
rdata1[width-2:0] <= i_rdata[width-1:1];
|
||||
end
|
||||
else
|
||||
always @(posedge i_clk) if (rtrig1) rdata1 <= i_rdata[1];
|
||||
endgenerate
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
rtrig1 <= rtrig0;
|
||||
rcnt <= rcnt+5'd1;
|
||||
if (i_rreq)
|
||||
rcnt <= 5'd0;
|
||||
|
||||
rreq_r <= i_rreq;
|
||||
o_rgnt <= rreq_r;
|
||||
|
||||
rdata0 <= {1'b0,rdata0[width-1:1]};
|
||||
if (rtrig0)
|
||||
rdata0 <= i_rdata;
|
||||
|
||||
if (i_rst) begin
|
||||
o_rgnt <= 1'b0;
|
||||
rreq_r <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
endmodule
|
|
@ -41,6 +41,8 @@ module serv_rf_top
|
|||
input wire i_dbus_ack);
|
||||
|
||||
parameter RESET_PC = 32'd0;
|
||||
parameter RF_WIDTH = 2;
|
||||
localparam RF_L2W = $clog2(RF_WIDTH);
|
||||
|
||||
wire rf_wreq;
|
||||
wire rf_rreq;
|
||||
|
@ -56,7 +58,13 @@ module serv_rf_top
|
|||
wire rdata0;
|
||||
wire rdata1;
|
||||
|
||||
serv_rf_2bit rf
|
||||
wire [10-RF_L2W:0] waddr;
|
||||
wire [RF_WIDTH-1:0] wdata;
|
||||
wire wen;
|
||||
wire [10-RF_L2W:0] raddr;
|
||||
wire [RF_WIDTH-1:0] rdata;
|
||||
|
||||
serv_rf_ram_if #(.width (RF_WIDTH)) rf_ram_if
|
||||
(.i_clk (clk),
|
||||
.i_rst (i_rst),
|
||||
.i_wreq (rf_wreq),
|
||||
|
@ -71,7 +79,20 @@ module serv_rf_top
|
|||
.i_rreg0 (rreg0),
|
||||
.i_rreg1 (rreg1),
|
||||
.o_rdata0 (rdata0),
|
||||
.o_rdata1 (rdata1));
|
||||
.o_rdata1 (rdata1),
|
||||
.o_waddr (waddr),
|
||||
.o_wdata (wdata),
|
||||
.o_wen (wen),
|
||||
.o_raddr (raddr),
|
||||
.i_rdata (rdata));
|
||||
|
||||
serv_rf_ram #(.width (RF_WIDTH)) rf_ram
|
||||
(.i_clk (clk),
|
||||
.i_waddr (waddr),
|
||||
.i_wdata (wdata),
|
||||
.i_wen (wen),
|
||||
.i_raddr (raddr),
|
||||
.o_rdata (rdata));
|
||||
|
||||
serv_top
|
||||
#(.RESET_PC (RESET_PC))
|
||||
|
|
|
@ -17,7 +17,8 @@ filesets:
|
|||
- rtl/serv_decode.v
|
||||
- rtl/serv_mem_if.v
|
||||
- rtl/serv_rf_if.v
|
||||
- rtl/serv_rf_2bit.v
|
||||
- rtl/serv_rf_ram_if.v
|
||||
- rtl/serv_rf_ram.v
|
||||
- rtl/serv_state.v
|
||||
- rtl/serv_top.v
|
||||
- rtl/serv_rf_top.v
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue