mirror of
https://github.com/olofk/serv.git
synced 2026-02-08 00:31:17 +00:00
Move dbus_dat/rs2/shamt storage to bufreg2
This commit is contained in:
65
rtl/serv_bufreg2.v
Normal file
65
rtl/serv_bufreg2.v
Normal file
@@ -0,0 +1,65 @@
|
||||
module serv_bufreg2
|
||||
(
|
||||
input wire i_clk,
|
||||
//State
|
||||
input wire i_en,
|
||||
input wire i_init,
|
||||
input wire i_cnt_done,
|
||||
input wire [1:0] i_lsb,
|
||||
input wire i_byte_valid,
|
||||
output wire o_sh_done,
|
||||
output wire o_sh_done_r,
|
||||
//Control
|
||||
input wire i_op_b_sel,
|
||||
input wire i_shift_op,
|
||||
//Data
|
||||
input wire i_rs2,
|
||||
input wire i_imm,
|
||||
output wire o_op_b,
|
||||
output wire o_q,
|
||||
//External
|
||||
output wire [31:0] o_dat,
|
||||
input wire i_load,
|
||||
input wire [31:0] i_dat);
|
||||
|
||||
reg [31:0] dat;
|
||||
|
||||
assign o_op_b = i_op_b_sel ? i_rs2 : i_imm;
|
||||
|
||||
wire dat_en = i_shift_op | (i_en & i_byte_valid);
|
||||
|
||||
/* The dat register has three different use cases for store, load and
|
||||
shift operations.
|
||||
store : Data to be written is shifted to the correct position in dat during
|
||||
init by dat_en and is presented on the data bus as o_wb_dat
|
||||
load : Data from the bus gets latched into dat during i_wb_ack and is then
|
||||
shifted out at the appropriate time to end up in the correct
|
||||
position in rd
|
||||
shift : Data is shifted in during init. After that, the six LSB are used as
|
||||
a downcounter (with bit 5 initially set to 0) that triggers
|
||||
o_sh_done and o_sh_done_r when they wrap around to indicate that
|
||||
the requested number of shifts have been performed
|
||||
*/
|
||||
wire [5:0] dat_shamt = (i_shift_op & !i_init) ?
|
||||
//Down counter mode
|
||||
dat[5:0]-1 :
|
||||
//Shift reg mode with optional clearing of bit 5
|
||||
{dat[6] & !(i_shift_op & i_cnt_done),dat[5:1]};
|
||||
|
||||
assign o_sh_done = dat_shamt[5];
|
||||
assign o_sh_done_r = dat[5];
|
||||
|
||||
assign o_q =
|
||||
((i_lsb == 2'd3) & dat[24]) |
|
||||
((i_lsb == 2'd2) & dat[16]) |
|
||||
((i_lsb == 2'd1) & dat[8]) |
|
||||
((i_lsb == 2'd0) & dat[0]);
|
||||
|
||||
assign o_dat = dat;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (dat_en | i_load)
|
||||
dat <= i_load ? i_dat : {o_op_b, dat[31:7], dat_shamt};
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -2,34 +2,25 @@
|
||||
module serv_mem_if
|
||||
#(parameter [0:0] WITH_CSR = 1)
|
||||
(
|
||||
input wire i_clk,
|
||||
input wire i_clk,
|
||||
//State
|
||||
input wire i_en,
|
||||
input wire i_init,
|
||||
input wire i_cnt_done,
|
||||
input wire [1:0] i_bytecnt,
|
||||
input wire [1:0] i_lsb,
|
||||
output wire o_misalign,
|
||||
output wire o_sh_done,
|
||||
output wire o_sh_done_r,
|
||||
input wire [1:0] i_bytecnt,
|
||||
input wire [1:0] i_lsb,
|
||||
output wire o_byte_valid,
|
||||
output wire o_misalign,
|
||||
//Control
|
||||
input wire i_shift_op,
|
||||
input wire i_signed,
|
||||
input wire i_word,
|
||||
input wire i_half,
|
||||
input wire i_signed,
|
||||
input wire i_word,
|
||||
input wire i_half,
|
||||
//MDU
|
||||
input wire i_mdu_op,
|
||||
input wire i_mdu_op,
|
||||
//Data
|
||||
input wire i_op_b,
|
||||
output wire o_rd,
|
||||
input wire i_bufreg2_q,
|
||||
output wire o_rd,
|
||||
//External interface
|
||||
output wire [31:0] o_wb_dat,
|
||||
output wire [3:0] o_wb_sel,
|
||||
input wire [31:0] i_wb_rdt,
|
||||
input wire i_wb_ack);
|
||||
output wire [3:0] o_wb_sel);
|
||||
|
||||
reg signbit;
|
||||
reg [31:0] dat;
|
||||
|
||||
/*
|
||||
Before a store operation, the data to be written needs to be shifted into
|
||||
@@ -39,62 +30,29 @@ module serv_mem_if
|
||||
clever enough so the hideous expression below is used to achieve the same
|
||||
thing in a more optimal way.
|
||||
*/
|
||||
wire byte_valid =
|
||||
(!i_lsb[0] & !i_lsb[1]) |
|
||||
(!i_bytecnt[0] & !i_bytecnt[1]) |
|
||||
(!i_bytecnt[1] & !i_lsb[1]) |
|
||||
(!i_bytecnt[1] & !i_lsb[0]) |
|
||||
(!i_bytecnt[0] & !i_lsb[1]);
|
||||
|
||||
wire dat_en = i_shift_op | (i_en & byte_valid);
|
||||
|
||||
wire dat_cur =
|
||||
((i_lsb == 2'd3) & dat[24]) |
|
||||
((i_lsb == 2'd2) & dat[16]) |
|
||||
((i_lsb == 2'd1) & dat[8]) |
|
||||
((i_lsb == 2'd0) & dat[0]);
|
||||
assign o_byte_valid
|
||||
= (!i_lsb[0] & !i_lsb[1]) |
|
||||
(!i_bytecnt[0] & !i_bytecnt[1]) |
|
||||
(!i_bytecnt[1] & !i_lsb[1]) |
|
||||
(!i_bytecnt[1] & !i_lsb[0]) |
|
||||
(!i_bytecnt[0] & !i_lsb[1]);
|
||||
|
||||
wire dat_valid =
|
||||
i_mdu_op |
|
||||
i_word |
|
||||
(i_bytecnt == 2'b00) |
|
||||
(i_half & !i_bytecnt[1]);
|
||||
|
||||
assign o_rd = (dat_valid|i_mdu_op) ? dat_cur : signbit & i_signed;
|
||||
assign o_rd = dat_valid ? i_bufreg2_q : signbit & i_signed;
|
||||
|
||||
assign o_wb_sel[3] = (i_lsb == 2'b11) | i_word | (i_half & i_lsb[1]);
|
||||
assign o_wb_sel[2] = (i_lsb == 2'b10) | i_word;
|
||||
assign o_wb_sel[1] = (i_lsb == 2'b01) | i_word | (i_half & !i_lsb[1]);
|
||||
assign o_wb_sel[0] = (i_lsb == 2'b00);
|
||||
|
||||
assign o_wb_dat = dat;
|
||||
|
||||
/* The dat register has three different use cases for store, load and
|
||||
shift operations.
|
||||
store : Data to be written is shifted to the correct position in dat during
|
||||
init by dat_en and is presented on the data bus as o_wb_dat
|
||||
load : Data from the bus gets latched into dat during i_wb_ack and is then
|
||||
shifted out at the appropriate time to end up in the correct
|
||||
position in rd
|
||||
shift : Data is shifted in during init. After that, the six LSB are used as
|
||||
a downcounter (with bit 5 initially set to 0) that triggers
|
||||
o_sh_done and o_sh_done_r when they wrap around to indicate that
|
||||
the requested number of shifts have been performed
|
||||
*/
|
||||
wire [5:0] dat_shamt = (i_shift_op & !i_init) ?
|
||||
//Down counter mode
|
||||
dat[5:0]-1 :
|
||||
//Shift reg mode with optional clearing of bit 5
|
||||
{dat[6] & !(i_shift_op & i_cnt_done),dat[5:1]};
|
||||
|
||||
assign o_sh_done = dat_shamt[5];
|
||||
assign o_sh_done_r = dat[5];
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (dat_en | i_wb_ack)
|
||||
dat <= i_wb_ack ? i_wb_rdt : {i_op_b, dat[31:7], dat_shamt};
|
||||
|
||||
if (dat_valid)
|
||||
signbit <= dat_cur;
|
||||
signbit <= i_bufreg2_q;
|
||||
end
|
||||
|
||||
/*
|
||||
|
||||
@@ -123,6 +123,7 @@ module serv_top
|
||||
wire bufreg_imm_en;
|
||||
wire bufreg_clr_lsb;
|
||||
wire bufreg_q;
|
||||
wire bufreg2_q;
|
||||
wire [31:0] dbus_rdt;
|
||||
wire dbus_ack;
|
||||
|
||||
@@ -137,14 +138,16 @@ module serv_top
|
||||
wire rs2;
|
||||
wire rd_en;
|
||||
|
||||
wire op_b_source;
|
||||
wire op_b;
|
||||
wire op_b_sel;
|
||||
|
||||
wire mem_signed;
|
||||
wire mem_word;
|
||||
wire mem_half;
|
||||
wire [1:0] mem_bytecnt;
|
||||
wire mem_sh_done;
|
||||
wire mem_sh_done_r;
|
||||
wire sh_done;
|
||||
wire sh_done_r;
|
||||
wire byte_valid;
|
||||
|
||||
wire mem_misalign;
|
||||
|
||||
@@ -168,7 +171,6 @@ module serv_top
|
||||
|
||||
wire [1:0] lsb;
|
||||
|
||||
wire op_b = op_b_source ? rs2 : imm;
|
||||
|
||||
serv_state
|
||||
#(.RESET_STRATEGY (RESET_STRATEGY),
|
||||
@@ -196,8 +198,8 @@ module serv_top
|
||||
.o_ctrl_jump (jump),
|
||||
.o_ctrl_trap (trap),
|
||||
.i_ctrl_misalign(lsb[1]),
|
||||
.i_sh_done (mem_sh_done),
|
||||
.i_sh_done_r (mem_sh_done_r),
|
||||
.i_sh_done (sh_done),
|
||||
.i_sh_done_r (sh_done_r),
|
||||
.o_mem_bytecnt (mem_bytecnt),
|
||||
.i_mem_misalign (mem_misalign),
|
||||
//Control
|
||||
@@ -251,19 +253,20 @@ module serv_top
|
||||
.o_two_stage_op (two_stage_op),
|
||||
//Extension
|
||||
.o_ext_funct3 (o_ext_funct3),
|
||||
|
||||
|
||||
//To bufreg
|
||||
.o_bufreg_rs1_en (bufreg_rs1_en),
|
||||
.o_bufreg_imm_en (bufreg_imm_en),
|
||||
.o_bufreg_clr_lsb (bufreg_clr_lsb),
|
||||
.o_bufreg_sh_signed (bufreg_sh_signed),
|
||||
//To bufreg2
|
||||
.o_op_b_source (op_b_sel),
|
||||
//To ctrl
|
||||
.o_ctrl_jal_or_jalr (jal_or_jalr),
|
||||
.o_ctrl_utype (utype),
|
||||
.o_ctrl_pc_rel (pc_rel),
|
||||
.o_ctrl_mret (mret),
|
||||
//To alu
|
||||
.o_op_b_source (op_b_source),
|
||||
.o_alu_sub (alu_sub),
|
||||
.o_alu_bool_op (alu_bool_op),
|
||||
.o_alu_cmp_eq (alu_cmp_eq),
|
||||
@@ -312,7 +315,7 @@ module serv_top
|
||||
.i_wb_en (i_ibus_ack),
|
||||
.i_wb_rdt (i_ibus_rdt[31:7]));
|
||||
|
||||
serv_bufreg
|
||||
serv_bufreg
|
||||
#(.MDU(MDU))
|
||||
bufreg
|
||||
(
|
||||
@@ -337,6 +340,30 @@ module serv_top
|
||||
.o_dbus_adr (o_dbus_adr),
|
||||
.o_ext_rs1 (o_ext_rs1));
|
||||
|
||||
serv_bufreg2 bufreg2
|
||||
(
|
||||
.i_clk (clk),
|
||||
//State
|
||||
.i_en (cnt_en),
|
||||
.i_init (init),
|
||||
.i_cnt_done (cnt_done),
|
||||
.i_lsb (lsb),
|
||||
.i_byte_valid (byte_valid),
|
||||
.o_sh_done (sh_done),
|
||||
.o_sh_done_r (sh_done_r),
|
||||
//Control
|
||||
.i_op_b_sel (op_b_sel),
|
||||
.i_shift_op (shift_op),
|
||||
//Data
|
||||
.i_rs2 (rs2),
|
||||
.i_imm (imm),
|
||||
.o_op_b (op_b),
|
||||
.o_q (bufreg2_q),
|
||||
//External
|
||||
.o_dat (o_dbus_dat),
|
||||
.i_load (dbus_ack),
|
||||
.i_dat (dbus_rdt));
|
||||
|
||||
serv_ctrl
|
||||
#(.RESET_PC (RESET_PC),
|
||||
.RESET_STRATEGY (RESET_STRATEGY),
|
||||
@@ -437,30 +464,22 @@ module serv_top
|
||||
#(.WITH_CSR (WITH_CSR))
|
||||
mem_if
|
||||
(
|
||||
.i_clk (clk),
|
||||
.i_clk (clk),
|
||||
//State
|
||||
.i_en (cnt_en),
|
||||
.i_init (init),
|
||||
.i_cnt_done (cnt_done),
|
||||
.i_bytecnt (mem_bytecnt),
|
||||
.i_lsb (lsb),
|
||||
.o_misalign (mem_misalign),
|
||||
.o_sh_done (mem_sh_done),
|
||||
.o_sh_done_r (mem_sh_done_r),
|
||||
.i_bytecnt (mem_bytecnt),
|
||||
.i_lsb (lsb),
|
||||
.o_byte_valid (byte_valid),
|
||||
.o_misalign (mem_misalign),
|
||||
//Control
|
||||
.i_mdu_op (mdu_op),
|
||||
.i_shift_op (shift_op),
|
||||
.i_signed (mem_signed),
|
||||
.i_word (mem_word),
|
||||
.i_half (mem_half),
|
||||
.i_mdu_op (mdu_op),
|
||||
.i_signed (mem_signed),
|
||||
.i_word (mem_word),
|
||||
.i_half (mem_half),
|
||||
//Data
|
||||
.i_op_b (op_b),
|
||||
.o_rd (mem_rd),
|
||||
.i_bufreg2_q (bufreg2_q),
|
||||
.o_rd (mem_rd),
|
||||
//External interface
|
||||
.o_wb_dat (o_dbus_dat),
|
||||
.o_wb_sel (o_dbus_sel),
|
||||
.i_wb_rdt (dbus_rdt),
|
||||
.i_wb_ack (dbus_ack));
|
||||
.o_wb_sel (o_dbus_sel));
|
||||
|
||||
generate
|
||||
if (WITH_CSR) begin
|
||||
@@ -579,7 +598,7 @@ generate
|
||||
assign dbus_rdt = i_ext_ready ? i_ext_rd:i_dbus_rdt;
|
||||
assign dbus_ack = i_dbus_ack | i_ext_ready;
|
||||
end else begin
|
||||
assign dbus_rdt = i_dbus_rdt;
|
||||
assign dbus_rdt = i_dbus_rdt;
|
||||
assign dbus_ack = i_dbus_ack;
|
||||
end
|
||||
assign o_ext_rs2 = o_dbus_dat;
|
||||
|
||||
Reference in New Issue
Block a user