Move dbus address handling to global bufreg

This commit is contained in:
Olof Kindgren 2019-01-15 07:57:47 +01:00
parent 9a97c535bd
commit fe33d6abdc
4 changed files with 67 additions and 44 deletions

40
rtl/serv_bufreg.v Normal file
View file

@ -0,0 +1,40 @@
module serv_bufreg
(
input wire i_clk,
input wire i_rst,
input wire [4:0] i_cnt,
input wire [3:0] i_cnt_r,
input wire i_en,
input wire i_clr,
input wire i_rs1,
input wire i_rs1_en,
input wire i_imm,
input wire i_imm_en,
output reg [1:0] o_lsb,
output wire [31:0] o_reg,
output wire o_q);
wire c, q;
reg c_r;
reg [31:0] data;
assign {c,q} = (i_rs1 & i_rs1_en) + (i_imm & i_imm_en) + c_r;
always @(posedge i_clk) begin
c_r <= c & !i_clr;
if (i_rst)
data <= 32'd0;
else if (i_en)
data <= {q, data[31:1]};
if ((i_cnt[4:2] == 3'd0) & i_cnt_r[0] & i_en)
o_lsb[0] <= q;
if ((i_cnt[4:2] == 3'd0) & i_cnt_r[1] & i_en)
o_lsb[1] <= q;
end
assign o_q = data[0];
assign o_reg = data;
endmodule

View file

@ -8,15 +8,12 @@ module serv_mem_if
input wire i_cmd,
input wire [1:0] i_bytecnt,
input wire [2:0] i_funct3,
input wire i_rs1,
input wire i_rs2,
input wire i_imm,
output wire o_rd,
input wire [1:0] i_lsb,
output reg o_misalign,
input wire i_trap,
output wire o_adr,
//External interface
output wire [31:0] o_wb_adr,
output wire [31:0] o_wb_dat,
output wire [3:0] o_wb_sel,
output wire o_wb_we ,
@ -26,8 +23,7 @@ module serv_mem_if
wire wb_en = o_wb_cyc & i_wb_ack;
reg init_r;
reg init_2r;
wire adr;
reg signbit = 1'b0;
reg [7:0] dat0;
@ -39,30 +35,6 @@ module serv_mem_if
wire dat2_en;
wire dat3_en;
assign o_adr = adr;
ser_add ser_add_rs1_plus_imm
(
.clk (i_clk),
.rst (i_rst),
.a (i_rs1),
.b (i_imm),
.clr (!i_en),
.q (adr),
.o_v ());
assign o_wb_adr[1:0] = 2'b00;
shift_reg #(30) shift_reg_adr
(
.clk (i_clk),
.i_rst (i_rst),
.i_en (i_init | i_trap),
.i_d (adr),
.o_q (o_wb_adr[2]),
.o_par (o_wb_adr[31:3])
);
wire dat_cur = (dat_sel == 3) ? dat3[0] :
(dat_sel == 2) ? dat2[0] :
(dat_sel == 1) ? dat1[0] : dat0[0];
@ -76,8 +48,6 @@ module serv_mem_if
wire is_half = i_funct3[0];
wire is_byte = !(|i_funct3[1:0]);
wire upper_half = bytepos[1];
/*
assign o_wb_sel = (is_word ? 4'b1111 :
@ -90,7 +60,7 @@ module serv_mem_if
assign o_wb_sel[0] = (bytepos == 2'b00);
assign o_wb_we = i_cmd;
reg [1:0] bytepos;
wire [1:0] bytepos;
wire wbyte0 = (i_bytecnt == 2'b00);
@ -107,6 +77,8 @@ module serv_mem_if
wire [1:0] dat_sel = i_bytecnt[1] ? i_bytecnt : (i_bytecnt | bytepos);
assign bytepos = i_lsb;
always @(posedge i_clk) begin
if (dat0_en)
dat0 <= {i_rs2, dat0[7:1]};
@ -120,17 +92,11 @@ module serv_mem_if
if (wb_en)
{dat3,dat2,dat1,dat0} <= i_wb_rdt;
if (i_init & !init_r)
bytepos[0] <= adr;
if (init_r & !init_2r)
bytepos[1] <= adr;
o_misalign <= i_en & ((bytepos[0] & !is_byte) | (bytepos[1] & is_word));
if (dat_valid)
signbit <= dat_cur;
init_r <= i_init;
init_2r <= init_r;
if (wb_en)
o_wb_cyc <= 1'b0;
else if (init_r & !i_init & !i_trap) begin //Optimize?
@ -139,7 +105,6 @@ module serv_mem_if
if (i_rst) begin
o_wb_cyc <= 1'b0;
init_r <= 1'b0;
init_2r <= 1'b0;
end
end
endmodule

View file

@ -189,6 +189,26 @@ module serv_top
.o_rd_alu_en (rd_alu_en),
.o_rd_mem_en (rd_mem_en));
wire [1:0] lsb;
wire [31:0] bufreg_out;
assign o_dbus_adr = {bufreg_out[31:2], 2'b00};
serv_bufreg bufreg
(
.i_clk (clk),
.i_rst (i_rst),
.i_cnt (cnt),
.i_cnt_r (cnt_r),
.i_en (alu_en),
.i_clr (!mem_en),
.i_rs1 (rs1),
.i_rs1_en (1'b1),
.i_imm (imm),
.i_imm_en (1'b1),
.o_lsb (lsb),
.o_reg (bufreg_out),
.o_q (bad_adr));
serv_ctrl
#(.RESET_PC (RESET_PC))
ctrl
@ -267,15 +287,12 @@ module serv_top
.i_cmd (mem_cmd),
.i_bytecnt (mem_bytecnt),
.i_funct3 (funct3),
.i_rs1 (rs1),
.i_rs2 (rs2),
.i_imm (imm),
.o_rd (mem_rd),
.i_lsb (lsb),
.o_misalign (mem_misalign),
.i_trap (trap),
.o_adr (bad_adr),
//External interface
.o_wb_adr (o_dbus_adr),
.o_wb_dat (o_dbus_dat),
.o_wb_sel (o_dbus_sel),
.o_wb_we (o_dbus_we ),

View file

@ -11,6 +11,7 @@ filesets:
- rtl/ser_eq.v
- rtl/ser_lt.v
- rtl/ser_shift.v
- rtl/serv_bufreg.v
- rtl/serv_alu.v
- rtl/serv_csr.v
- rtl/serv_ctrl.v