mirror of
https://github.com/olofk/serv.git
synced 2026-01-13 23:25:57 +00:00
77 lines
1.5 KiB
Verilog
77 lines
1.5 KiB
Verilog
`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,
|
|
input wire i_rs_en,
|
|
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_rs_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 = (|i_rs1_addr) & rs1_r;
|
|
assign o_rs2 = (|i_rs2_addr) & (rs1_en ? rs2 : rdata[0]);
|
|
|
|
wire [8:0] waddr = {i_rd_addr, wcnt[4:1]};
|
|
wire wr_en = wcnt[0] & i_rd_en;
|
|
|
|
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
|
|
endmodule
|