Rewrite register file

This commit is contained in:
Olof Kindgren 2018-11-26 00:09:52 +01:00
parent a974320f46
commit e1f5bcc4f3
6 changed files with 64 additions and 1333 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,12 +0,0 @@
CAPI=2:
name : yosys:techlibs:ice40fork:0.7
filesets:
ice40_cells:
files:
- cells_sim.v : {file_type : verilogSource}
targets:
default:
filesets : [ice40_cells]

View file

@ -5,6 +5,7 @@ module serv_decode
input wire i_rst,
input wire [31:0] i_wb_rdt,
input wire i_wb_en,
input wire i_rf_ready,
output wire o_cnt_done,
output wire o_ctrl_en,
output wire o_ctrl_pc_en,
@ -35,7 +36,6 @@ module serv_decode
output wire o_mem_cmd,
output wire o_mem_init,
output wire [1:0] o_mem_bytecnt,
input wire i_mem_dbus_ack,
input wire i_mem_misalign,
output wire o_csr_en,
output reg [2:0] o_csr_sel,
@ -72,7 +72,6 @@ module serv_decode
OP_SYSTEM = 5'b11100;
reg [1:0] state;
reg go;
reg [4:0] cnt;
@ -231,7 +230,7 @@ module serv_decode
op <= i_wb_rdt[30:7];
signbit <= i_wb_rdt[31];
end
if (cnt_done | go | i_mem_dbus_ack) begin
if (cnt_done | i_rf_ready) begin
imm19_12_20 <= {op[19:12],op[20]};
imm7 <= op[7];
imm30_25 <= op[30:25];
@ -274,12 +273,6 @@ module serv_decode
assign o_rd_csr_en = opcode[2] & opcode[4];
assign o_rd_mem_en = !opcode[2] & !opcode[4];
always @(posedge clk) begin
go <= i_wb_en;
if (i_rst)
go <= 1'b0;
end
wire cnt_en = (state != IDLE);
wire cnt_done = cnt == 31;
@ -298,25 +291,28 @@ module serv_decode
wire two_stage_op =
slt_op | (opcode[4:2] == 3'b110) | (opcode[2:1] == 2'b00) |
shift_op;
reg stage_one_done;
always @(posedge clk) begin
case (state)
IDLE : begin
if (go) begin
if (i_rf_ready) begin
state <= RUN;
if (two_stage_op)
if (two_stage_op & !stage_one_done)
state <= INIT;
if (e_op)
state <= TRAP;
end
if (i_mem_dbus_ack)
state <= RUN;
end
INIT : begin
stage_one_done <= 1'b1;
if (cnt_done)
state <= (i_mem_misalign | (o_ctrl_jump & i_ctrl_misalign)) ? TRAP :
mem_op ? IDLE : RUN;
end
RUN : begin
stage_one_done <= 1'b0;
if (cnt_done)
state <= IDLE;
end

View file

@ -2,6 +2,8 @@
module serv_regfile
(
input wire i_clk,
input wire i_go,
output reg o_ready,
input wire i_rd_en,
input wire [4:0] i_rd_addr,
input wire i_rd,
@ -11,56 +13,55 @@ module serv_regfile
output wire o_rs1,
output wire o_rs2);
reg [4:0] raddr = 5'd1;
reg [4:0] waddr = 5'd0;
wire [31:0] rs;
wire [4:0] raddr2 = raddr & {5{i_rs_en}};
reg [31:0] mask;
always @(i_rd_addr)
mask = ~(1 << i_rd_addr);
SB_RAM40_4K rf0
(
.RDATA (rs[15:0]),
.RCLK (i_clk),
.RCLKE (1'b1),
.RE (1'b1),
.RADDR ({6'd0,raddr2}),
.WCLK (i_clk),
.WCLKE (1'b1),
.WE (i_rd_en),
.WADDR ({6'd0,waddr}),
.MASK (mask[15:0]),
.WDATA ({16{i_rd}})
);
SB_RAM40_4K rf1
(
.RDATA (rs[31:16]),
.RCLK (i_clk),
.RCLKE (1'b1),
.RE (1'b1),
.RADDR ({6'd0,raddr2}),
.WCLK (i_clk),
.WCLKE (1'b1),
.WE (i_rd_en),
.WADDR ({6'd0,waddr}),
.MASK (mask[31:16]),
.WDATA ({16{i_rd}})
);
reg t;
always @(posedge i_clk) begin
if (i_rd_en) begin
waddr <= waddr + 1;
end
if (i_rs_en)
raddr <= raddr + 1;
o_ready <= t;
t <= i_go;
end
assign o_rs1 = (|i_rs1_addr) ? rs[i_rs1_addr] : 1'b0;
assign o_rs2 = (|i_rs2_addr) ? rs[i_rs2_addr] : 1'b0;
reg rd_r;
reg [4:0] rcnt;
reg [4:0] wcnt;
reg rs1;
reg rs2;
reg rs1_r;
wire [1:0] wdata = {i_rd, rd_r};
always @(posedge i_clk) begin
rd_r <= i_rd;
if (i_rs_en)
wcnt <= wcnt + 1;
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;
end
wire rs1_tmp = (rs1_en ? rdata[0] : rs1);
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]};
wire rs1_en = rcnt[0];
reg [1:0] memory [0:511];
reg [1:0] rdata;
always @(posedge i_clk) begin
if (wr_en)
memory[waddr] <= wdata;
rdata <= memory[raddr];
end
endmodule

View file

@ -85,6 +85,7 @@ module serv_top
wire alu_sh_right;
wire [2:0] alu_rd_sel;
wire rf_ready;
wire rs1;
wire rs2;
wire rs_en;
@ -121,6 +122,7 @@ module serv_top
.i_rst (i_rst),
.i_wb_rdt (i_ibus_rdt),
.i_wb_en (o_ibus_cyc & i_ibus_ack),
.i_rf_ready (rf_ready),
.o_cnt_done (cnt_done),
.o_ctrl_en (ctrl_en),
.o_ctrl_pc_en (ctrl_pc_en),
@ -152,7 +154,6 @@ module serv_top
.o_mem_cmd (mem_cmd),
.o_mem_init (mem_init),
.o_mem_bytecnt (mem_bytecnt),
.i_mem_dbus_ack (i_dbus_ack),
.i_mem_misalign (mem_misalign),
.o_csr_en (csr_en),
.o_csr_sel (csr_sel),
@ -220,6 +221,8 @@ module serv_top
serv_regfile regfile
(
.i_clk (clk),
.i_go (i_ibus_ack | i_dbus_ack),
.o_ready (rf_ready),
.i_rd_en (rd_en),
.i_rd_addr (rd_addr),
.i_rd (rd),

View file

@ -30,10 +30,8 @@ filesets:
files:
- bench/serv_top_tb.v
file_type : verilogSource
depend : [vlog_tb_utils, "yosys:techlibs:ice40"]
depend : [vlog_tb_utils]
techlib:
depend : ["yosys:techlibs:ice40fork"]
wrapper:
files:
- rtl/riscv_timer.v
@ -58,7 +56,6 @@ filesets:
verilator_tb:
files:
- bench/serv_soc_tb.cpp : {file_type : verilogSource}
depend : ["yosys:techlibs:ice40"]
targets:
default:
@ -90,7 +87,7 @@ targets:
lint:
default_tool : verilator
filesets : [core, techlib]
filesets : [core]
tools:
verilator:
mode : lint-only