Format sv and v code.

This commit is contained in:
colin 2022-05-23 14:16:04 +00:00
parent 2f8715aeb6
commit 6bf845bb46
45 changed files with 21059 additions and 16680 deletions

View File

@ -116,8 +116,30 @@ import el2_pkg::*;
);
typedef enum logic [3:0] {IDLE=4'h0, HALTING=4'h1, HALTED=4'h2, CORE_CMD_START=4'h3, CORE_CMD_WAIT=4'h4, SB_CMD_START=4'h5, SB_CMD_SEND=4'h6, SB_CMD_RESP=4'h7, CMD_DONE=4'h8, RESUMING=4'h9} state_t;
typedef enum logic [3:0] {SBIDLE=4'h0, WAIT_RD=4'h1, WAIT_WR=4'h2, CMD_RD=4'h3, CMD_WR=4'h4, CMD_WR_ADDR=4'h5, CMD_WR_DATA=4'h6, RSP_RD=4'h7, RSP_WR=4'h8, DONE=4'h9} sb_state_t;
typedef enum logic [3:0] {
IDLE = 4'h0,
HALTING = 4'h1,
HALTED = 4'h2,
CORE_CMD_START = 4'h3,
CORE_CMD_WAIT = 4'h4,
SB_CMD_START = 4'h5,
SB_CMD_SEND = 4'h6,
SB_CMD_RESP = 4'h7,
CMD_DONE = 4'h8,
RESUMING = 4'h9
} state_t;
typedef enum logic [3:0] {
SBIDLE = 4'h0,
WAIT_RD = 4'h1,
WAIT_WR = 4'h2,
CMD_RD = 4'h3,
CMD_WR = 4'h4,
CMD_WR_ADDR = 4'h5,
CMD_WR_DATA = 4'h6,
RSP_RD = 4'h7,
RSP_WR = 4'h8,
DONE = 4'h9
} sb_state_t;
state_t dbg_state;
state_t dbg_nxtstate;
@ -141,7 +163,14 @@ import el2_pkg::*;
logic abstractcs_busy_wren;
logic abstractcs_busy_din;
logic [2:0] abstractcs_error_din;
logic abstractcs_error_sel0, abstractcs_error_sel1, abstractcs_error_sel2, abstractcs_error_sel3, abstractcs_error_sel4, abstractcs_error_sel5, abstractcs_error_sel6;
logic
abstractcs_error_sel0,
abstractcs_error_sel1,
abstractcs_error_sel2,
abstractcs_error_sel3,
abstractcs_error_sel4,
abstractcs_error_sel5,
abstractcs_error_sel6;
logic dbg_sb_bus_error;
// abstractauto
logic abstractauto_reg_wren;
@ -264,8 +293,16 @@ import el2_pkg::*;
// used for the system bus
assign sb_free_clken = dmi_reg_en | execute_command | sb_state_en | (sb_state != SBIDLE) | clk_override;
rvoclkhdr dbg_free_cgc (.en(dbg_free_clken), .l1clk(dbg_free_clk), .*);
rvoclkhdr sb_free_cgc (.en(sb_free_clken), .l1clk(sb_free_clk), .*);
rvoclkhdr dbg_free_cgc (
.en(dbg_free_clken),
.l1clk(dbg_free_clk),
.*
);
rvoclkhdr sb_free_cgc (
.en(sb_free_clken),
.l1clk(sb_free_clk),
.*
);
// end clocking section
@ -274,7 +311,12 @@ import el2_pkg::*;
assign dbg_core_rst_l = ~dmcontrol_reg[1] | scan_mode;
// synchronize the rst
rvsyncss #(1) rstl_syncff (.din(rst_l), .dout(rst_l_sync), .clk(free_clk), .rst_l(dbg_rst_l));
rvsyncss #(1) rstl_syncff (
.din (rst_l),
.dout (rst_l_sync),
.clk (free_clk),
.rst_l(dbg_rst_l)
);
// system bus register
// sbcs[31:29], sbcs - [22]:sbbusyerror, [21]: sbbusy, [20]:sbreadonaddr, [19:17]:sbaccess, [16]:sbautoincrement, [15]:sbreadondata, [14:12]:sberror, sbsize=32, 128=0, 64/32/16/8 are legal
@ -288,12 +330,41 @@ import el2_pkg::*;
(sbcs_reg[21] & dmi_reg_en & ((dmi_reg_wr_en & (dmi_reg_addr == 7'h39)) | (dmi_reg_addr == 7'h3c) | (dmi_reg_addr == 7'h3d)));
assign sbcs_sbbusyerror_din = ~(sbcs_wren & dmi_reg_wdata[22]); // Clear when writing one
rvdffs #(1) sbcs_sbbusyerror_reg (.din(sbcs_sbbusyerror_din), .dout(sbcs_reg[22]), .en(sbcs_sbbusyerror_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
rvdffs #(1) sbcs_sbbusy_reg (.din(sbcs_sbbusy_din), .dout(sbcs_reg[21]), .en(sbcs_sbbusy_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
rvdffs #(1) sbcs_sbreadonaddr_reg (.din(dmi_reg_wdata[20]), .dout(sbcs_reg[20]), .en(sbcs_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
rvdffs #(5) sbcs_misc_reg (.din({dmi_reg_wdata[19],~dmi_reg_wdata[18],dmi_reg_wdata[17:15]}),
.dout(sbcs_reg_int[19:15]), .en(sbcs_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
rvdffs #(3) sbcs_error_reg (.din(sbcs_sberror_din[2:0]), .dout(sbcs_reg[14:12]), .en(sbcs_sberror_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
rvdffs #(1) sbcs_sbbusyerror_reg (
.din(sbcs_sbbusyerror_din),
.dout(sbcs_reg[22]),
.en(sbcs_sbbusyerror_wren),
.rst_l(dbg_dm_rst_l),
.clk(sb_free_clk)
);
rvdffs #(1) sbcs_sbbusy_reg (
.din(sbcs_sbbusy_din),
.dout(sbcs_reg[21]),
.en(sbcs_sbbusy_wren),
.rst_l(dbg_dm_rst_l),
.clk(sb_free_clk)
);
rvdffs #(1) sbcs_sbreadonaddr_reg (
.din(dmi_reg_wdata[20]),
.dout(sbcs_reg[20]),
.en(sbcs_wren),
.rst_l(dbg_dm_rst_l),
.clk(sb_free_clk)
);
rvdffs #(5) sbcs_misc_reg (
.din({dmi_reg_wdata[19], ~dmi_reg_wdata[18], dmi_reg_wdata[17:15]}),
.dout(sbcs_reg_int[19:15]),
.en(sbcs_wren),
.rst_l(dbg_dm_rst_l),
.clk(sb_free_clk)
);
rvdffs #(3) sbcs_error_reg (
.din(sbcs_sberror_din[2:0]),
.dout(sbcs_reg[14:12]),
.en(sbcs_sberror_wren),
.rst_l(dbg_dm_rst_l),
.clk(sb_free_clk)
);
assign sbcs_unaligned = ((sbcs_reg[19:17] == 3'b001) & sbaddress0_reg[0]) |
((sbcs_reg[19:17] == 3'b010) & (|sbaddress0_reg[1:0])) |
@ -320,15 +391,33 @@ import el2_pkg::*;
assign sbdata1_din[31:0] = ({32{sbdata1_reg_wren0}} & dmi_reg_wdata[31:0]) |
({32{sbdata1_reg_wren1}} & sb_bus_rdata[63:32]);
rvdffe #(32) dbg_sbdata0_reg (.*, .din(sbdata0_din[31:0]), .dout(sbdata0_reg[31:0]), .en(sbdata0_reg_wren), .rst_l(dbg_dm_rst_l));
rvdffe #(32) dbg_sbdata1_reg (.*, .din(sbdata1_din[31:0]), .dout(sbdata1_reg[31:0]), .en(sbdata1_reg_wren), .rst_l(dbg_dm_rst_l));
rvdffe #(32) dbg_sbdata0_reg (
.*,
.din(sbdata0_din[31:0]),
.dout(sbdata0_reg[31:0]),
.en(sbdata0_reg_wren),
.rst_l(dbg_dm_rst_l)
);
rvdffe #(32) dbg_sbdata1_reg (
.*,
.din(sbdata1_din[31:0]),
.dout(sbdata1_reg[31:0]),
.en(sbdata1_reg_wren),
.rst_l(dbg_dm_rst_l)
);
// sbaddress
assign sbaddress0_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h39);
assign sbaddress0_reg_wren = sbaddress0_reg_wren0 | sbaddress0_reg_wren1;
assign sbaddress0_reg_din[31:0]= ({32{sbaddress0_reg_wren0}} & dmi_reg_wdata[31:0]) |
({32{sbaddress0_reg_wren1}} & (sbaddress0_reg[31:0] + {28'b0,sbaddress0_incr[3:0]}));
rvdffe #(32) dbg_sbaddress0_reg (.*, .din(sbaddress0_reg_din[31:0]), .dout(sbaddress0_reg[31:0]), .en(sbaddress0_reg_wren), .rst_l(dbg_dm_rst_l));
rvdffe #(32) dbg_sbaddress0_reg (
.*,
.din(sbaddress0_reg_din[31:0]),
.dout(sbaddress0_reg[31:0]),
.en(sbaddress0_reg_wren),
.rst_l(dbg_dm_rst_l)
);
assign sbreadonaddr_access = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h39) & sbcs_reg[20]; // if readonaddr is set the next command will start upon writing of addr0
assign sbreadondata_access = dmi_reg_en & ~dmi_reg_wr_en & (dmi_reg_addr == 7'h3c) & sbcs_reg[15]; // if readondata is set the next command will start upon reading of data0
@ -342,9 +431,26 @@ import el2_pkg::*;
assign dmcontrol_reg[29] = '0;
assign dmcontrol_reg[27:2] = '0;
assign resumereq = dmcontrol_reg[30] & ~dmcontrol_reg[31] & dmcontrol_wren_Q;
rvdffs #(4) dmcontrolff (.din({dmi_reg_wdata[31:30],dmi_reg_wdata[28],dmi_reg_wdata[1]}), .dout({dmcontrol_reg[31:30], dmcontrol_reg[28], dmcontrol_reg[1]}), .en(dmcontrol_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdffs #(1) dmcontrol_dmactive_ff (.din(dmi_reg_wdata[0]), .dout(dmcontrol_reg[0]), .en(dmcontrol_wren), .rst_l(dbg_rst_l), .clk(dbg_free_clk));
rvdff #(1) dmcontrol_wrenff(.din(dmcontrol_wren), .dout(dmcontrol_wren_Q), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdffs #(4) dmcontrolff (
.din({dmi_reg_wdata[31:30], dmi_reg_wdata[28], dmi_reg_wdata[1]}),
.dout({dmcontrol_reg[31:30], dmcontrol_reg[28], dmcontrol_reg[1]}),
.en(dmcontrol_wren),
.rst_l(dbg_dm_rst_l),
.clk(dbg_free_clk)
);
rvdffs #(1) dmcontrol_dmactive_ff (
.din(dmi_reg_wdata[0]),
.dout(dmcontrol_reg[0]),
.en(dmcontrol_wren),
.rst_l(dbg_rst_l),
.clk(dbg_free_clk)
);
rvdff #(1) dmcontrol_wrenff (
.din (dmcontrol_wren),
.dout (dmcontrol_wren_Q),
.rst_l(dbg_dm_rst_l),
.clk (dbg_free_clk)
);
// dmstatus register bits that are implemented
// [19:18]-havereset,[17:16]-resume ack, [9:8]-halted, [3:0]-version
@ -370,9 +476,26 @@ import el2_pkg::*;
assign dmstatus_unavail = dmcontrol_reg[1] | ~rst_l_sync;
assign dmstatus_running = ~(dmstatus_unavail | dmstatus_halted);
rvdffs #(1) dmstatus_resumeack_reg (.din(dmstatus_resumeack_din), .dout(dmstatus_resumeack), .en(dmstatus_resumeack_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdff #(1) dmstatus_halted_reg (.din(dec_tlu_dbg_halted & ~dec_tlu_mpc_halted_only), .dout(dmstatus_halted), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdffs #(1) dmstatus_haveresetn_reg (.din(1'b1), .dout(dmstatus_haveresetn), .en(dmstatus_haveresetn_wren), .rst_l(rst_l), .clk(dbg_free_clk));
rvdffs #(1) dmstatus_resumeack_reg (
.din(dmstatus_resumeack_din),
.dout(dmstatus_resumeack),
.en(dmstatus_resumeack_wren),
.rst_l(dbg_dm_rst_l),
.clk(dbg_free_clk)
);
rvdff #(1) dmstatus_halted_reg (
.din (dec_tlu_dbg_halted & ~dec_tlu_mpc_halted_only),
.dout (dmstatus_halted),
.rst_l(dbg_dm_rst_l),
.clk (dbg_free_clk)
);
rvdffs #(1) dmstatus_haveresetn_reg (
.din(1'b1),
.dout(dmstatus_haveresetn),
.en(dmstatus_haveresetn_wren),
.rst_l(rst_l),
.clk(dbg_free_clk)
);
// haltsum0 register
assign haltsum0_reg[31:1] = '0;
@ -410,12 +533,30 @@ import el2_pkg::*;
abstractcs_error_sel6 ? (~dmi_reg_wdata[10:8] & abstractcs_reg[10:8]) : //W1C
abstractcs_reg[10:8]; //hold
rvdffs #(1) dmabstractcs_busy_reg (.din(abstractcs_busy_din), .dout(abstractcs_reg[12]), .en(abstractcs_busy_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdff #(3) dmabstractcs_error_reg (.din(abstractcs_error_din[2:0]), .dout(abstractcs_reg[10:8]), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdffs #(1) dmabstractcs_busy_reg (
.din(abstractcs_busy_din),
.dout(abstractcs_reg[12]),
.en(abstractcs_busy_wren),
.rst_l(dbg_dm_rst_l),
.clk(dbg_free_clk)
);
rvdff #(3) dmabstractcs_error_reg (
.din (abstractcs_error_din[2:0]),
.dout (abstractcs_reg[10:8]),
.rst_l(dbg_dm_rst_l),
.clk (dbg_free_clk)
);
// abstract auto reg
assign abstractauto_reg_wren = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h18) & ~abstractcs_reg[12];
rvdffs #(2) dbg_abstractauto_reg (.*, .din(dmi_reg_wdata[1:0]), .dout(abstractauto_reg[1:0]), .en(abstractauto_reg_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdffs #(2) dbg_abstractauto_reg (
.*,
.din(dmi_reg_wdata[1:0]),
.dout(abstractauto_reg[1:0]),
.en(abstractauto_reg_wren),
.rst_l(dbg_dm_rst_l),
.clk(dbg_free_clk)
);
// command register - implemented all the bits in this register
// command[16] = 1: write, 0: read
@ -425,11 +566,36 @@ import el2_pkg::*;
assign command_regno_wren = command_wren | ((command_reg[31:24] == 8'h0) & command_reg[19] & (dbg_state == CMD_DONE) & ~(|abstractcs_reg[10:8])); // aarpostincrement
assign command_postexec_din = (dmi_reg_wdata[31:24] == 8'h0) & dmi_reg_wdata[18];
assign command_transfer_din = (dmi_reg_wdata[31:24] == 8'h0) & dmi_reg_wdata[17];
assign command_din[31:16] = {dmi_reg_wdata[31:24],1'b0,dmi_reg_wdata[22:19],command_postexec_din,command_transfer_din, dmi_reg_wdata[16]};
assign command_din[31:16] = {
dmi_reg_wdata[31:24],
1'b0,
dmi_reg_wdata[22:19],
command_postexec_din,
command_transfer_din,
dmi_reg_wdata[16]
};
assign command_din[15:0] = command_wren ? dmi_reg_wdata[15:0] : dbg_cmd_next_addr[15:0];
rvdff #(1) execute_commandff (.*, .din(execute_command_ns), .dout(execute_command), .clk(dbg_free_clk), .rst_l(dbg_dm_rst_l));
rvdffe #(16) dmcommand_reg (.*, .din(command_din[31:16]), .dout(command_reg[31:16]), .en(command_wren), .rst_l(dbg_dm_rst_l));
rvdffe #(16) dmcommand_regno_reg (.*, .din(command_din[15:0]), .dout(command_reg[15:0]), .en(command_regno_wren), .rst_l(dbg_dm_rst_l));
rvdff #(1) execute_commandff (
.*,
.din (execute_command_ns),
.dout (execute_command),
.clk (dbg_free_clk),
.rst_l(dbg_dm_rst_l)
);
rvdffe #(16) dmcommand_reg (
.*,
.din(command_din[31:16]),
.dout(command_reg[31:16]),
.en(command_wren),
.rst_l(dbg_dm_rst_l)
);
rvdffe #(16) dmcommand_regno_reg (
.*,
.din(command_din[15:0]),
.dout(command_reg[15:0]),
.en(command_regno_wren),
.rst_l(dbg_dm_rst_l)
);
// data0 reg
assign data0_reg_wren0 = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h4) & (dbg_state == HALTED) & ~abstractcs_reg[12]);
@ -440,7 +606,13 @@ import el2_pkg::*;
({32{data0_reg_wren1}} & core_dbg_rddata[31:0]) |
({32{data0_reg_wren2}} & sb_bus_rdata[31:0]);
rvdffe #(32) dbg_data0_reg (.*, .din(data0_din[31:0]), .dout(data0_reg[31:0]), .en(data0_reg_wren), .rst_l(dbg_dm_rst_l));
rvdffe #(32) dbg_data0_reg (
.*,
.din(data0_din[31:0]),
.dout(data0_reg[31:0]),
.en(data0_reg_wren),
.rst_l(dbg_dm_rst_l)
);
// data 1
assign data1_reg_wren0 = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h5) & (dbg_state == HALTED) & ~abstractcs_reg[12]);
@ -450,10 +622,30 @@ import el2_pkg::*;
assign data1_din[31:0] = ({32{data1_reg_wren0}} & dmi_reg_wdata[31:0]) |
({32{data1_reg_wren1}} & dbg_cmd_next_addr[31:0]);
rvdffe #(32) dbg_data1_reg (.*, .din(data1_din[31:0]), .dout(data1_reg[31:0]), .en(data1_reg_wren), .rst_l(dbg_dm_rst_l));
rvdffe #(32) dbg_data1_reg (
.*,
.din(data1_din[31:0]),
.dout(data1_reg[31:0]),
.en(data1_reg_wren),
.rst_l(dbg_dm_rst_l)
);
rvdffs #(1) sb_abmem_cmd_doneff (.din(sb_abmem_cmd_done_in), .dout(sb_abmem_cmd_done), .en(sb_abmem_cmd_done_en), .clk(dbg_free_clk), .rst_l(dbg_dm_rst_l), .*);
rvdffs #(1) sb_abmem_data_doneff (.din(sb_abmem_data_done_in), .dout(sb_abmem_data_done), .en(sb_abmem_data_done_en), .clk(dbg_free_clk), .rst_l(dbg_dm_rst_l), .*);
rvdffs #(1) sb_abmem_cmd_doneff (
.din(sb_abmem_cmd_done_in),
.dout(sb_abmem_cmd_done),
.en(sb_abmem_cmd_done_en),
.clk(dbg_free_clk),
.rst_l(dbg_dm_rst_l),
.*
);
rvdffs #(1) sb_abmem_data_doneff (
.din(sb_abmem_data_done_in),
.dout(sb_abmem_data_done),
.en(sb_abmem_data_done_en),
.clk(dbg_free_clk),
.rst_l(dbg_dm_rst_l),
.*
);
// FSM to control the debug mode entry, command send/recieve, and Resume flow.
always_comb begin
@ -561,8 +753,23 @@ import el2_pkg::*;
({32{dmi_reg_addr == 7'h3d}} & sbdata1_reg[31:0]);
rvdffs #($bits(state_t)) dbg_state_reg (.din(dbg_nxtstate), .dout({dbg_state}), .en(dbg_state_en), .rst_l(dbg_dm_rst_l & rst_l), .clk(dbg_free_clk));
rvdffe #(32) dmi_rddata_reg (.din(dmi_reg_rdata_din[31:0]), .dout(dmi_reg_rdata[31:0]), .en(dmi_reg_en), .rst_l(dbg_dm_rst_l), .clk(clk), .*);
rvdffs #($bits(
state_t
)) dbg_state_reg (
.din(dbg_nxtstate),
.dout({dbg_state}),
.en(dbg_state_en),
.rst_l(dbg_dm_rst_l & rst_l),
.clk(dbg_free_clk)
);
rvdffe #(32) dmi_rddata_reg (
.din(dmi_reg_rdata_din[31:0]),
.dout(dmi_reg_rdata[31:0]),
.en(dmi_reg_en),
.rst_l(dbg_dm_rst_l),
.clk(clk),
.*
);
assign abmem_addr[31:0] = data1_reg[31:0];
assign abmem_addr_core_local = (abmem_addr_in_dccm_region | abmem_addr_in_iccm_region | abmem_addr_in_pic_region);
@ -668,7 +875,15 @@ import el2_pkg::*;
endcase
end // always_comb begin
rvdffs #($bits(sb_state_t)) sb_state_reg (.din(sb_nxtstate), .dout({sb_state}), .en(sb_state_en), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
rvdffs #($bits(
sb_state_t
)) sb_state_reg (
.din(sb_nxtstate),
.dout({sb_state}),
.en(sb_state_en),
.rst_l(dbg_dm_rst_l),
.clk(sb_free_clk)
);
assign sb_abmem_cmd_write = command_reg[16];
assign sb_abmem_cmd_size[2:0] = {1'b0, command_reg[21:20]};

View File

@ -31,8 +31,7 @@ module el2_dec
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
input logic free_clk, // Clock always. Through two clock headers. For flops without second clock header built in.
@ -273,7 +272,9 @@ import el2_pkg::*;
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] i0_predict_index_d, // DEC predict index
output logic [pt.BTB_BTAG_SIZE-1:0] i0_predict_btag_d, // DEC predict branch tag
output logic [$clog2(pt.BTB_SIZE)-1:0] dec_fa_error_index, // Fully associt btb error index
output logic [$clog2(
pt.BTB_SIZE
)-1:0] dec_fa_error_index, // Fully associt btb error index
output logic dec_lsu_valid_raw_d,
@ -406,17 +407,27 @@ import el2_pkg::*;
el2_dec_tlu_ctl #(.pt(pt)) tlu (.*);
el2_dec_gpr_ctl #(.pt(pt)) arf (.*,
el2_dec_gpr_ctl #(
.pt(pt)
) arf (
.*,
// inputs
.raddr0(dec_i0_rs1_d[4:0]),
.raddr1(dec_i0_rs2_d[4:0]),
.wen0(dec_i0_wen_r), .waddr0(dec_i0_waddr_r[4:0]), .wd0(dec_i0_wdata_r[31:0]),
.wen1(dec_nonblock_load_wen), .waddr1(dec_nonblock_load_waddr[4:0]), .wd1(lsu_nonblock_load_data[31:0]),
.wen2(exu_div_wren), .waddr2(div_waddr_wb), .wd2(exu_div_result[31:0]),
.wen0(dec_i0_wen_r),
.waddr0(dec_i0_waddr_r[4:0]),
.wd0(dec_i0_wdata_r[31:0]),
.wen1(dec_nonblock_load_wen),
.waddr1(dec_nonblock_load_waddr[4:0]),
.wd1(lsu_nonblock_load_data[31:0]),
.wen2(exu_div_wren),
.waddr2(div_waddr_wb),
.wd2(exu_div_result[31:0]),
// outputs
.rd0(gpr_i0_rs1_d[31:0]), .rd1(gpr_i0_rs2_d[31:0])
.rd0(gpr_i0_rs1_d[31:0]),
.rd1(gpr_i0_rs2_d[31:0])
);

View File

@ -18,8 +18,7 @@ module el2_dec_decode_ctl
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic dec_tlu_trace_disable,
input logic dec_debug_valid_d,
@ -178,7 +177,9 @@ import el2_pkg::*;
output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] i0_predict_index_d, // i0 predict index
output logic [pt.BTB_BTAG_SIZE-1:0] i0_predict_btag_d, // i0_predict branch tag
output logic [$clog2(pt.BTB_SIZE)-1:0] dec_fa_error_index, // Fully associt btb error index
output logic [$clog2(
pt.BTB_SIZE
)-1:0] dec_fa_error_index, // Fully associt btb error index
output logic [1:0] dec_data_en, // clock-gating logic
output logic [1:0] dec_ctl_en,
@ -432,16 +433,44 @@ import el2_pkg::*;
el2_reg_pkt_t i0r;
rvdffie #(8) misc1ff (.*,
rvdffie #(8) misc1ff (
.*,
.clk(free_l2clk),
.din( {leak1_i1_stall_in,leak1_i0_stall_in,dec_tlu_flush_extint,pause_state_in ,dec_tlu_wr_pause_r, tlu_wr_pause_r1,illegal_lockout_in,ps_stall_in}),
.dout({leak1_i1_stall, leak1_i0_stall, dec_extint_stall, pause_state, tlu_wr_pause_r1,tlu_wr_pause_r2,illegal_lockout, ps_stall })
.din({
leak1_i1_stall_in,
leak1_i0_stall_in,
dec_tlu_flush_extint,
pause_state_in,
dec_tlu_wr_pause_r,
tlu_wr_pause_r1,
illegal_lockout_in,
ps_stall_in
}),
.dout({
leak1_i1_stall,
leak1_i0_stall,
dec_extint_stall,
pause_state,
tlu_wr_pause_r1,
tlu_wr_pause_r2,
illegal_lockout,
ps_stall
})
);
rvdffie #(8) misc2ff (.*,
rvdffie #(8) misc2ff (
.*,
.clk(free_l2clk),
.din( {lsu_trigger_match_m[3:0],lsu_pmu_misaligned_m,div_active_in,exu_flush_final, dec_debug_valid_d}),
.dout({lsu_trigger_match_r[3:0],lsu_pmu_misaligned_r,div_active, flush_final_r, debug_valid_x})
.din({
lsu_trigger_match_m[3:0],
lsu_pmu_misaligned_m,
div_active_in,
exu_flush_final,
dec_debug_valid_d
}),
.dout({
lsu_trigger_match_r[3:0], lsu_pmu_misaligned_r, div_active, flush_final_r, debug_valid_x
})
);
if (pt.BTB_ENABLE == 1) begin
@ -487,14 +516,17 @@ if(pt.BTB_ENABLE==1) begin
assign btb_error_found = (i0_br_error_all | btb_error_found_f) & ~dec_tlu_flush_lower_r;
assign fa_error_index_ns = (i0_br_error_all & ~btb_error_found_f) ? dec_i0_bp_fa_index : dec_fa_error_index;
rvdff #($clog2(pt.BTB_SIZE)+1) btberrorfa_f (.*, .clk(active_clk),
rvdff #($clog2(
pt.BTB_SIZE
) + 1) btberrorfa_f (
.*,
.clk (active_clk),
.din ({btb_error_found, fa_error_index_ns}),
.dout({btb_error_found_f, dec_fa_error_index}));
.dout({btb_error_found_f, dec_fa_error_index})
);
end
else
assign dec_fa_error_index = 'b0;
end else assign dec_fa_error_index = 'b0;
// end
@ -607,13 +639,10 @@ end // else: !if(pt.BTB_ENABLE==1)
if (~cam[i].valid) begin
cam_wen[i] = cam_write;
found = 1'b1;
end
else begin
end else begin
cam_wen[i] = 0;
end
end
else
cam_wen[i] = 0;
end else cam_wen[i] = 0;
end
end
@ -641,8 +670,7 @@ end // else: !if(pt.BTB_ENABLE==1)
cam[i] = cam_raw[i];
if (cam_data_reset_val[i])
cam[i].valid = 1'b0;
if (cam_data_reset_val[i]) cam[i].valid = 1'b0;
cam_in[i] = '0;
@ -655,19 +683,23 @@ end // else: !if(pt.BTB_ENABLE==1)
else if ( (cam_inv_reset_val[i]) |
(i0_wen_r & (r_d_in.i0rd[4:0] == cam[i].rd[4:0]) & cam[i].wb) )
cam_in[i].valid = 1'b0;
else
cam_in[i] = cam[i];
else cam_in[i] = cam[i];
if (nonblock_load_valid_m_delay & (lsu_nonblock_load_inv_tag_r[NBLOAD_TAG_MSB:0]==cam[i].tag[NBLOAD_TAG_MSB:0]) & cam[i].valid)
cam_in[i].wb = 1'b1;
// force debug halt forces cam valids to 0; highest priority
if (dec_tlu_force_halt)
cam_in[i].valid = 1'b0;
if (dec_tlu_force_halt) cam_in[i].valid = 1'b0;
end
rvdffie #( $bits(el2_load_cam_pkt_t) ) cam_ff (.*, .din(cam_in[i]), .dout(cam_raw[i]));
rvdffie #($bits(
el2_load_cam_pkt_t
)) cam_ff (
.*,
.din (cam_in[i]),
.dout(cam_raw[i])
);
assign nonblock_load_write[i] = (load_data_tag[NBLOAD_TAG_MSB:0] == cam_raw[i].tag[NBLOAD_TAG_MSB:0]) & cam_raw[i].valid;
@ -704,7 +736,13 @@ end : cam_array
// don't writeback a nonblock load
rvdffs #(1) wbnbloaddelayff (.*, .clk(active_clk), .en(i0_r_ctl_en ), .din(lsu_nonblock_load_valid_m), .dout(nonblock_load_valid_m_delay) );
rvdffs #(1) wbnbloaddelayff (
.*,
.clk (active_clk),
.en (i0_r_ctl_en),
.din (lsu_nonblock_load_valid_m),
.dout(nonblock_load_valid_m_delay)
);
assign i0_load_kill_wen_r = nonblock_load_valid_m_delay & r_d.i0load;
@ -757,12 +795,20 @@ end : cam_array
// end pmu
el2_dec_dec_ctl i0_dec (.inst(i0[31:0]),.out(i0_dp_raw));
el2_dec_dec_ctl i0_dec (
.inst(i0[31:0]),
.out (i0_dp_raw)
);
rvdff #(1) lsu_idle_ff (.*, .clk(active_clk), .din(lsu_idle_any), .dout(lsu_idle));
rvdff #(1) lsu_idle_ff (
.*,
.clk (active_clk),
.din (lsu_idle_any),
.dout(lsu_idle)
);
@ -848,8 +894,7 @@ end : cam_array
lsu_p.word = 1'b1;
lsu_p.fast_int = 1'b1;
lsu_p.valid = 1'b1;
end
else begin
end else begin
lsu_p.valid = lsu_decode_d;
lsu_p.load = i0_dp.load;
@ -917,7 +962,8 @@ end : cam_array
assign dec_csr_stall_int_ff = ((r_d.csrwaddr[11:0] == 12'h300) | (r_d.csrwaddr[11:0] == 12'h304)) & r_d.csrwen & r_d.i0valid & ~dec_tlu_i0_kill_writeb_wb;
rvdff #(5) csrmiscff (.*,
rvdff #(5) csrmiscff (
.*,
.clk (active_clk),
.din ({csr_ren_qual_d, csr_clr_d, csr_set_d, csr_write_d, i0_dp.csr_imm}),
.dout({csr_read_x, csr_clr_x, csr_set_x, csr_write_x, csr_imm_x})
@ -928,7 +974,12 @@ end : cam_array
// perform the update operation if any
rvdffe #(37) csr_rddata_x_ff (.*, .en(i0_x_data_en & any_csr_d), .din( {i0[19:15],dec_csr_rddata_d[31:0]}), .dout({csrimm_x[4:0],csr_rddata_x[31:0]}));
rvdffe #(37) csr_rddata_x_ff (
.*,
.en (i0_x_data_en & any_csr_d),
.din ({i0[19:15], dec_csr_rddata_d[31:0]}),
.dout({csrimm_x[4:0], csr_rddata_x[31:0]})
);
assign csr_mask_x[31:0] = ({32{ csr_imm_x}} & {27'b0,csrimm_x[4:0]}) |
@ -967,7 +1018,13 @@ end : cam_array
(dec_tlu_wr_pause_r) ? dec_csr_wrdata_r[31:0] : write_csr_data_x[31:0];
// will hold until write-back at which time the CSR will be updated while GPR is possibly written with prior CSR
rvdffe #(32) write_csr_ff (.*, .clk(free_l2clk), .en(csr_data_wen), .din(write_csr_data_in[31:0]), .dout(write_csr_data[31:0]));
rvdffe #(32) write_csr_ff (
.*,
.clk (free_l2clk),
.en (csr_data_wen),
.din (write_csr_data_in[31:0]),
.dout(write_csr_data[31:0])
);
assign pause_stall = pause_state;
@ -1047,54 +1104,35 @@ end : cam_array
// block reads if there is a prior csr write in the pipeline
assign prior_csr_write = x_d.csrwonly |
r_d.csrwonly |
wbd.csrwonly;
assign prior_csr_write = x_d.csrwonly | r_d.csrwonly | wbd.csrwonly;
if (pt.BITMANIP_ZBB == 1)
assign bitmanip_zbb_legal = 1'b1;
else
assign bitmanip_zbb_legal = ~(i0_dp.zbb & ~i0_dp.zbp);
if (pt.BITMANIP_ZBB == 1) assign bitmanip_zbb_legal = 1'b1;
else assign bitmanip_zbb_legal = ~(i0_dp.zbb & ~i0_dp.zbp);
if (pt.BITMANIP_ZBS == 1)
assign bitmanip_zbs_legal = 1'b1;
else
assign bitmanip_zbs_legal = ~i0_dp.zbs;
if (pt.BITMANIP_ZBS == 1) assign bitmanip_zbs_legal = 1'b1;
else assign bitmanip_zbs_legal = ~i0_dp.zbs;
if (pt.BITMANIP_ZBE == 1)
assign bitmanip_zbe_legal = 1'b1;
else
assign bitmanip_zbe_legal = ~(i0_dp.zbe & ~i0_dp.zbp & ~i0_dp.zbf);
if (pt.BITMANIP_ZBE == 1) assign bitmanip_zbe_legal = 1'b1;
else assign bitmanip_zbe_legal = ~(i0_dp.zbe & ~i0_dp.zbp & ~i0_dp.zbf);
if (pt.BITMANIP_ZBC == 1)
assign bitmanip_zbc_legal = 1'b1;
else
assign bitmanip_zbc_legal = ~i0_dp.zbc;
if (pt.BITMANIP_ZBC == 1) assign bitmanip_zbc_legal = 1'b1;
else assign bitmanip_zbc_legal = ~i0_dp.zbc;
if (pt.BITMANIP_ZBP == 1)
assign bitmanip_zbp_legal = 1'b1;
else
assign bitmanip_zbp_legal = ~(i0_dp.zbp & ~i0_dp.zbb & ~i0_dp.zbe & ~i0_dp.zbf);
if (pt.BITMANIP_ZBP == 1) assign bitmanip_zbp_legal = 1'b1;
else assign bitmanip_zbp_legal = ~(i0_dp.zbp & ~i0_dp.zbb & ~i0_dp.zbe & ~i0_dp.zbf);
if (pt.BITMANIP_ZBR == 1)
assign bitmanip_zbr_legal = 1'b1;
else
assign bitmanip_zbr_legal = ~i0_dp.zbr;
if (pt.BITMANIP_ZBR == 1) assign bitmanip_zbr_legal = 1'b1;
else assign bitmanip_zbr_legal = ~i0_dp.zbr;
if (pt.BITMANIP_ZBF == 1)
assign bitmanip_zbf_legal = 1'b1;
else
assign bitmanip_zbf_legal = ~(i0_dp.zbf & ~i0_dp.zbp & ~i0_dp.zbe);
if (pt.BITMANIP_ZBF == 1) assign bitmanip_zbf_legal = 1'b1;
else assign bitmanip_zbf_legal = ~(i0_dp.zbf & ~i0_dp.zbp & ~i0_dp.zbe);
if (pt.BITMANIP_ZBA == 1)
assign bitmanip_zba_legal = 1'b1;
else
assign bitmanip_zba_legal = ~i0_dp.zba;
if (pt.BITMANIP_ZBA == 1) assign bitmanip_zba_legal = 1'b1;
else assign bitmanip_zba_legal = ~i0_dp.zba;
if ( (pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1) )
assign bitmanip_zbb_zbp_legal = 1'b1;
if ((pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1)) assign bitmanip_zbb_zbp_legal = 1'b1;
else
assign bitmanip_zbb_zbp_legal = ~(i0_dp.zbb & i0_dp.zbp & ~i0_dp.zbf); // added ~ZBF to exclude ZEXT.H
@ -1123,7 +1161,12 @@ end : cam_array
assign illegal_inst_en = shift_illegal & ~illegal_lockout;
rvdffe #(32) illegal_any_ff (.*, .en(illegal_inst_en), .din(i0_inst_d[31:0]), .dout(dec_illegal_inst[31:0]));
rvdffe #(32) illegal_any_ff (
.*,
.en (illegal_inst_en),
.din (i0_inst_d[31:0]),
.dout(dec_illegal_inst[31:0])
);
assign illegal_lockout_in = (shift_illegal | illegal_lockout) & ~flush_final_r;
@ -1204,8 +1247,7 @@ end : cam_array
assign store_data_bypass_d = i0_dp.store & i0_rs2_depth_d[1] & i0_rs2_class_d.load;
assign store_data_bypass_m = i0_dp.store & i0_rs2_depth_d[0] & i0_rs2_class_d.load;
end
else begin : genblock
end else begin : genblock
assign i0_load_block_d = 1'b0;
@ -1241,7 +1283,15 @@ end : cam_array
rvdfflie #( .WIDTH($bits(el2_trap_pkt_t)),.LEFT(9) ) trap_xff (.*, .en(i0_x_ctl_en), .din(d_t), .dout(x_t));
rvdfflie #(
.WIDTH($bits(el2_trap_pkt_t)),
.LEFT (9)
) trap_xff (
.*,
.en (i0_x_ctl_en),
.din (d_t),
.dout(x_t)
);
always_comb begin
x_t_in = x_t;
@ -1249,7 +1299,15 @@ end : cam_array
end
rvdfflie #( .WIDTH($bits(el2_trap_pkt_t)),.LEFT(9) ) trap_r_ff (.*, .en(i0_x_ctl_en), .din(x_t_in), .dout(r_t));
rvdfflie #(
.WIDTH($bits(el2_trap_pkt_t)),
.LEFT (9)
) trap_r_ff (
.*,
.en (i0_x_ctl_en),
.din (x_t_in),
.dout(r_t)
);
always_comb begin
@ -1279,8 +1337,24 @@ end : cam_array
assign i0_d_c.load = i0_dp.load & i0_legal_decode_d;
assign i0_d_c.alu = i0_dp.alu & i0_legal_decode_d;
rvdffs #( $bits(el2_class_pkt_t) ) i0_x_c_ff (.*, .en(i0_x_ctl_en), .clk(active_clk), .din(i0_d_c), .dout(i0_x_c));
rvdffs #( $bits(el2_class_pkt_t) ) i0_r_c_ff (.*, .en(i0_r_ctl_en), .clk(active_clk), .din(i0_x_c), .dout(i0_r_c));
rvdffs #($bits(
el2_class_pkt_t
)) i0_x_c_ff (
.*,
.en (i0_x_ctl_en),
.clk (active_clk),
.din (i0_d_c),
.dout(i0_x_c)
);
rvdffs #($bits(
el2_class_pkt_t
)) i0_r_c_ff (
.*,
.en (i0_r_ctl_en),
.clk (active_clk),
.din (i0_x_c),
.dout(i0_r_c)
);
assign d_d.i0rd[4:0] = i0r.rd[4:0];
@ -1297,7 +1371,12 @@ end : cam_array
assign d_d.csrwaddr[11:0] = (d_d.csrwen) ? i0[31:20] : '0; // csr write address for rd==0 case
rvdff #(3) i0cgff (.*, .clk(active_clk), .din(i0_pipe_en[3:1]), .dout(i0_pipe_en[2:0]));
rvdff #(3) i0cgff (
.*,
.clk (active_clk),
.din (i0_pipe_en[3:1]),
.dout(i0_pipe_en[2:0])
);
assign i0_pipe_en[3] = dec_i0_decode_d;
@ -1313,7 +1392,15 @@ end : cam_array
rvdfflie #( .WIDTH($bits(el2_dest_pkt_t)),.LEFT(15) ) e1ff (.*, .en(i0_x_ctl_en), .din(d_d), .dout(x_d));
rvdfflie #(
.WIDTH($bits(el2_dest_pkt_t)),
.LEFT (15)
) e1ff (
.*,
.en (i0_x_ctl_en),
.din (d_d),
.dout(x_d)
);
always_comb begin
x_d_in = x_d;
@ -1322,7 +1409,15 @@ end : cam_array
x_d_in.i0valid = x_d.i0valid & ~dec_tlu_flush_lower_wb & ~dec_tlu_flush_lower_r;
end
rvdfflie #( .WIDTH($bits(el2_dest_pkt_t)), .LEFT(15) ) r_d_ff (.*, .en(i0_r_ctl_en), .din(x_d_in), .dout(r_d));
rvdfflie #(
.WIDTH($bits(el2_dest_pkt_t)),
.LEFT (15)
) r_d_ff (
.*,
.en (i0_r_ctl_en),
.din (x_d_in),
.dout(r_d)
);
always_comb begin
@ -1342,7 +1437,15 @@ end : cam_array
end
rvdfflie #(.WIDTH($bits(el2_dest_pkt_t)), .LEFT(15)) wbff (.*, .en(i0_wb_ctl_en), .din(r_d_in), .dout(wbd));
rvdfflie #(
.WIDTH($bits(el2_dest_pkt_t)),
.LEFT (15)
) wbff (
.*,
.en (i0_wb_ctl_en),
.din (r_d_in),
.dout(wbd)
);
assign dec_i0_waddr_r[4:0] = r_d_in.i0rd[4:0];
@ -1352,8 +1455,7 @@ end : cam_array
// divide stuff
assign div_e1_to_r = (x_d.i0div & x_d.i0valid) |
(r_d.i0div & r_d.i0valid);
assign div_e1_to_r = (x_d.i0div & x_d.i0valid) | (r_d.i0div & r_d.i0valid);
assign div_active_in = i0_div_decode_d | (div_active & ~exu_div_wren & ~nonblock_div_cancel);
@ -1386,20 +1488,29 @@ end : cam_array
if (pt.LOAD_TO_USE_PLUS1 == 1) begin : genblock1
assign i0_result_x[31:0] = exu_i0_result_x[31:0];
assign i0_result_r[31:0] = (r_d.i0v & r_d.i0load) ? lsu_result_m[31:0] : i0_result_r_raw[31:0];
end
else begin : genblock1
end else begin : genblock1
assign i0_result_x[31:0] = (x_d.i0v & x_d.i0load) ? lsu_result_m[31:0] : exu_i0_result_x[31:0];
assign i0_result_r[31:0] = i0_result_r_raw[31:0];
end
rvdffe #(32) i0_result_r_ff (.*, .en(i0_r_data_en & (x_d.i0v | x_d.csrwen | debug_valid_x)), .din(i0_result_x[31:0]), .dout(i0_result_r_raw[31:0]));
rvdffe #(32) i0_result_r_ff (
.*,
.en (i0_r_data_en & (x_d.i0v | x_d.csrwen | debug_valid_x)),
.din (i0_result_x[31:0]),
.dout(i0_result_r_raw[31:0])
);
// correct lsu load data - don't use for bypass, do pass down the pipe
assign i0_result_corr_r[31:0] = (r_d.i0v & r_d.i0load) ? lsu_result_corr_r[31:0] : i0_result_r_raw[31:0];
rvdffe #(12) e1brpcff (.*, .en(i0_x_data_en), .din(last_br_immed_d[12:1] ), .dout(last_br_immed_x[12:1]));
rvdffe #(12) e1brpcff (
.*,
.en (i0_x_data_en),
.din (last_br_immed_d[12:1]),
.dout(last_br_immed_x[12:1])
);
@ -1412,20 +1523,53 @@ end : cam_array
assign trace_enable = ~dec_tlu_trace_disable;
rvdffe #(.WIDTH(5),.OVERRIDE(1)) i0rdff (.*, .en(i0_div_decode_d), .din(i0r.rd[4:0]), .dout(div_waddr_wb[4:0]));
rvdffe #(
.WIDTH(5),
.OVERRIDE(1)
) i0rdff (
.*,
.en (i0_div_decode_d),
.din (i0r.rd[4:0]),
.dout(div_waddr_wb[4:0])
);
rvdffe #(32) i0xinstff (.*, .en(i0_x_data_en & trace_enable), .din(i0_inst_d[31:0]), .dout(i0_inst_x[31:0]));
rvdffe #(32) i0cinstff (.*, .en(i0_r_data_en & trace_enable), .din(i0_inst_x[31:0]), .dout(i0_inst_r[31:0]));
rvdffe #(32) i0xinstff (
.*,
.en (i0_x_data_en & trace_enable),
.din (i0_inst_d[31:0]),
.dout(i0_inst_x[31:0])
);
rvdffe #(32) i0cinstff (
.*,
.en (i0_r_data_en & trace_enable),
.din (i0_inst_x[31:0]),
.dout(i0_inst_r[31:0])
);
rvdffe #(32) i0wbinstff (.*, .en(i0_wb_en & trace_enable), .din(i0_inst_wb_in[31:0]), .dout(i0_inst_wb[31:0]));
rvdffe #(31) i0wbpcff (.*, .en(i0_wb_en & trace_enable), .din(dec_tlu_i0_pc_r[31:1]), .dout( i0_pc_wb[31:1]));
rvdffe #(32) i0wbinstff (
.*,
.en (i0_wb_en & trace_enable),
.din (i0_inst_wb_in[31:0]),
.dout(i0_inst_wb[31:0])
);
rvdffe #(31) i0wbpcff (
.*,
.en (i0_wb_en & trace_enable),
.din (dec_tlu_i0_pc_r[31:1]),
.dout(i0_pc_wb[31:1])
);
assign dec_i0_inst_wb[31:0] = i0_inst_wb[31:0];
assign dec_i0_pc_wb[31:1] = i0_pc_wb[31:1];
rvdffpcie #(31) i0_pc_r_ff (.*, .en(i0_r_data_en), .din(exu_i0_pc_x[31:1]), .dout(dec_i0_pc_r[31:1]));
rvdffpcie #(31) i0_pc_r_ff (
.*,
.en (i0_r_data_en),
.din (exu_i0_pc_x[31:1]),
.dout(dec_i0_pc_r[31:1])
);
assign dec_tlu_i0_pc_r[31:1] = dec_i0_pc_r[31:1];
@ -1433,7 +1577,8 @@ end : cam_array
rvbradder ibradder_correct (
.pc(exu_i0_pc_x[31:1]),
.offset(last_br_immed_x[12:1]),
.dout(pred_correct_npc_x[31:1]));
.dout(pred_correct_npc_x[31:1])
);

View File

@ -50,7 +50,12 @@ import el2_pkg::*;
// GPR Write Enables
assign gpr_wr_en[31:1] = (w0v[31:1] | w1v[31:1] | w2v[31:1]);
for (genvar j = 1; j < 32; j++) begin : gpr
rvdffe #(32) gprff (.*, .en(gpr_wr_en[j]), .din(gpr_in[j][31:0]), .dout(gpr_out[j][31:0]));
rvdffe #(32) gprff (
.*,
.en (gpr_wr_en[j]),
.din (gpr_in[j][31:0]),
.dout(gpr_out[j][31:0])
);
end : gpr
// the read out

View File

@ -17,8 +17,7 @@ module el2_dec_ib_ctl
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic dbg_cmd_valid, // valid dbg cmd
input logic dbg_cmd_write, // dbg cmd is write
@ -83,8 +82,9 @@ import el2_pkg::*;
logic [34:0] ifu_i0_pcdata, pc0;
assign ifu_i0_pcdata[34:0] = { ifu_i0_icaf_second, ifu_i0_dbecc, ifu_i0_icaf,
ifu_i0_pc[31:1], ifu_i0_pc4 };
assign ifu_i0_pcdata[34:0] = {
ifu_i0_icaf_second, ifu_i0_dbecc, ifu_i0_icaf, ifu_i0_pc[31:1], ifu_i0_pc4
};
assign pc0[34:0] = ifu_i0_pcdata[34:0];

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,12 @@ import el2_pkg::*;
for (genvar i = 0; i < 4; i++) begin
assign dec_i0_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select & trigger_pkt_any[i].execute}} & {dec_i0_pc_d[31:1], trigger_pkt_any[i].tdata2[0]}); // select=0; do a PC match
rvmaskandmatch trigger_i0_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(dec_i0_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(dec_i0_trigger_data_match[i]));
rvmaskandmatch trigger_i0_match (
.mask (trigger_pkt_any[i].tdata2[31:0]),
.data (dec_i0_match_data[i][31:0]),
.masken(trigger_pkt_any[i].match),
.match (dec_i0_trigger_data_match[i])
);
assign dec_i0_trigger_match_d[i] = trigger_pkt_any[i].execute & trigger_pkt_any[i].m & dec_i0_trigger_data_match[i];
end

View File

@ -50,8 +50,7 @@ always @ ( posedge clk or negedge rst_n) begin
if (!rst_n) begin
rden <= '0;
wren <= '0;
end
else begin
end else begin
rden <= {rden[1:0], rd_en};
wren <= {wren[1:0], wr_en};
end

View File

@ -15,8 +15,7 @@
module rvjtag_tap #(
parameter AWIDTH = 7
)
(
) (
input trst,
input tck,
input tms,
@ -153,8 +152,7 @@ assign dr_en[1] = ir == 5'b10001;
always @(posedge tck or negedge trst) begin
if (!trst) begin
sr <= '0;
end
else begin
end else begin
sr <= nsr;
end
end
@ -193,12 +191,10 @@ always @ (posedge tck or negedge trst) begin
if (!trst) begin
dmi_hard_reset <= 1'b0;
dmi_reset <= 1'b0;
end
else if (update_dr & dr_en[0]) begin
end else if (update_dr & dr_en[0]) begin
dmi_hard_reset <= sr[17];
dmi_reset <= sr[16];
end
else begin
end else begin
dmi_hard_reset <= 1'b0;
dmi_reset <= 1'b0;
end
@ -206,13 +202,10 @@ end
// DR register
always @(posedge tck or negedge trst) begin
if(!trst)
dr <= '0;
if (!trst) dr <= '0;
else begin
if (update_dr & dr_en[1])
dr <= sr;
else
dr <= {dr[USER_DR_LENGTH-1:2],2'b0};
if (update_dr & dr_en[1]) dr <= sr;
else dr <= {dr[USER_DR_LENGTH-1:2], 2'b0};
end
end

View File

@ -259,22 +259,122 @@ module el2_dma_ctrl #(
((dccm_dma_rvalid & (i == DEPTH_PTR'(dccm_dma_rtag[2:0]))) ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid & (i == DEPTH_PTR'(iccm_dma_rtag[2:0]))) ? iccm_dma_rdata[63:0] :
(dbg_cmd_valid ? {2{dma_dbg_mem_wrdata[31:0]}} : bus_cmd_wdata[63:0]));
rvdffsc #(1) fifo_valid_dff (.din(1'b1), .dout(fifo_valid[i]), .en(fifo_cmd_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
rvdffsc #(2) fifo_error_dff (.din(fifo_error_in[i]), .dout(fifo_error[i]), .en(fifo_error_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
rvdffsc #(1) fifo_error_bus_dff (.din(1'b1), .dout(fifo_error_bus[i]), .en(fifo_error_bus_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
rvdffsc #(1) fifo_rpend_dff (.din(1'b1), .dout(fifo_rpend[i]), .en(fifo_pend_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
rvdffsc #(1) fifo_done_dff (.din(1'b1), .dout(fifo_done[i]), .en(fifo_done_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
rvdffsc #(1) fifo_done_bus_dff (.din(1'b1), .dout(fifo_done_bus[i]), .en(fifo_done_bus_en[i]), .clear(fifo_reset[i]), .clk(dma_free_clk), .*);
rvdffe #(32) fifo_addr_dff (.din(fifo_addr_in[31:0]), .dout(fifo_addr[i]), .en(fifo_cmd_en[i]), .*);
rvdffs #(3) fifo_sz_dff (.din(fifo_sz_in[2:0]), .dout(fifo_sz[i]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
rvdffs #(8) fifo_byteen_dff (.din(fifo_byteen_in[7:0]), .dout(fifo_byteen[i]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
rvdffs #(1) fifo_write_dff (.din(fifo_write_in), .dout(fifo_write[i]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
rvdffs #(1) fifo_posted_write_dff (.din(fifo_posted_write_in), .dout(fifo_posted_write[i]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
rvdffs #(1) fifo_dbg_dff (.din(fifo_dbg_in), .dout(fifo_dbg[i]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
rvdffe #(64) fifo_data_dff (.din(fifo_data_in[i]), .dout(fifo_data[i]), .en(fifo_data_en[i]), .*);
rvdffs #(pt.DMA_BUS_TAG) fifo_tag_dff(.din(bus_cmd_tag[pt.DMA_BUS_TAG-1:0]), .dout(fifo_tag[i][pt.DMA_BUS_TAG-1:0]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
rvdffs #(pt.DMA_BUS_ID) fifo_mid_dff(.din(bus_cmd_mid[pt.DMA_BUS_ID-1:0]), .dout(fifo_mid[i][pt.DMA_BUS_ID-1:0]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
rvdffs #(pt.DMA_BUS_PRTY) fifo_prty_dff(.din(bus_cmd_prty[pt.DMA_BUS_PRTY-1:0]), .dout(fifo_prty[i][pt.DMA_BUS_PRTY-1:0]), .en(fifo_cmd_en[i]), .clk(dma_buffer_c1_clk), .*);
rvdffsc #(1) fifo_valid_dff (
.din(1'b1),
.dout(fifo_valid[i]),
.en(fifo_cmd_en[i]),
.clear(fifo_reset[i]),
.clk(dma_free_clk),
.*
);
rvdffsc #(2) fifo_error_dff (
.din(fifo_error_in[i]),
.dout(fifo_error[i]),
.en(fifo_error_en[i]),
.clear(fifo_reset[i]),
.clk(dma_free_clk),
.*
);
rvdffsc #(1) fifo_error_bus_dff (
.din(1'b1),
.dout(fifo_error_bus[i]),
.en(fifo_error_bus_en[i]),
.clear(fifo_reset[i]),
.clk(dma_free_clk),
.*
);
rvdffsc #(1) fifo_rpend_dff (
.din(1'b1),
.dout(fifo_rpend[i]),
.en(fifo_pend_en[i]),
.clear(fifo_reset[i]),
.clk(dma_free_clk),
.*
);
rvdffsc #(1) fifo_done_dff (
.din(1'b1),
.dout(fifo_done[i]),
.en(fifo_done_en[i]),
.clear(fifo_reset[i]),
.clk(dma_free_clk),
.*
);
rvdffsc #(1) fifo_done_bus_dff (
.din(1'b1),
.dout(fifo_done_bus[i]),
.en(fifo_done_bus_en[i]),
.clear(fifo_reset[i]),
.clk(dma_free_clk),
.*
);
rvdffe #(32) fifo_addr_dff (
.din (fifo_addr_in[31:0]),
.dout(fifo_addr[i]),
.en (fifo_cmd_en[i]),
.*
);
rvdffs #(3) fifo_sz_dff (
.din (fifo_sz_in[2:0]),
.dout(fifo_sz[i]),
.en (fifo_cmd_en[i]),
.clk (dma_buffer_c1_clk),
.*
);
rvdffs #(8) fifo_byteen_dff (
.din (fifo_byteen_in[7:0]),
.dout(fifo_byteen[i]),
.en (fifo_cmd_en[i]),
.clk (dma_buffer_c1_clk),
.*
);
rvdffs #(1) fifo_write_dff (
.din (fifo_write_in),
.dout(fifo_write[i]),
.en (fifo_cmd_en[i]),
.clk (dma_buffer_c1_clk),
.*
);
rvdffs #(1) fifo_posted_write_dff (
.din (fifo_posted_write_in),
.dout(fifo_posted_write[i]),
.en (fifo_cmd_en[i]),
.clk (dma_buffer_c1_clk),
.*
);
rvdffs #(1) fifo_dbg_dff (
.din (fifo_dbg_in),
.dout(fifo_dbg[i]),
.en (fifo_cmd_en[i]),
.clk (dma_buffer_c1_clk),
.*
);
rvdffe #(64) fifo_data_dff (
.din (fifo_data_in[i]),
.dout(fifo_data[i]),
.en (fifo_data_en[i]),
.*
);
rvdffs #(pt.DMA_BUS_TAG) fifo_tag_dff (
.din (bus_cmd_tag[pt.DMA_BUS_TAG-1:0]),
.dout(fifo_tag[i][pt.DMA_BUS_TAG-1:0]),
.en (fifo_cmd_en[i]),
.clk (dma_buffer_c1_clk),
.*
);
rvdffs #(pt.DMA_BUS_ID) fifo_mid_dff (
.din (bus_cmd_mid[pt.DMA_BUS_ID-1:0]),
.dout(fifo_mid[i][pt.DMA_BUS_ID-1:0]),
.en (fifo_cmd_en[i]),
.clk (dma_buffer_c1_clk),
.*
);
rvdffs #(pt.DMA_BUS_PRTY) fifo_prty_dff (
.din (bus_cmd_prty[pt.DMA_BUS_PRTY-1:0]),
.dout(fifo_prty[i][pt.DMA_BUS_PRTY-1:0]),
.en (fifo_cmd_en[i]),
.clk (dma_buffer_c1_clk),
.*
);
end
// Pointer logic
@ -286,9 +386,27 @@ module el2_dma_ctrl #(
assign RdPtrEn = dma_dccm_req | dma_iccm_req | (dma_address_error | dma_alignment_error | dma_dbg_cmd_error);
assign RspPtrEn = (dma_dbg_cmd_done | (bus_rsp_sent | bus_posted_write_done) & dma_bus_clk_en);
rvdffs #(DEPTH_PTR) WrPtr_dff(.din(NxtWrPtr[DEPTH_PTR-1:0]), .dout(WrPtr[DEPTH_PTR-1:0]), .en(WrPtrEn), .clk(dma_free_clk), .*);
rvdffs #(DEPTH_PTR) RdPtr_dff(.din(NxtRdPtr[DEPTH_PTR-1:0]), .dout(RdPtr[DEPTH_PTR-1:0]), .en(RdPtrEn), .clk(dma_free_clk), .*);
rvdffs #(DEPTH_PTR) RspPtr_dff(.din(NxtRspPtr[DEPTH_PTR-1:0]), .dout(RspPtr[DEPTH_PTR-1:0]), .en(RspPtrEn), .clk(dma_free_clk), .*);
rvdffs #(DEPTH_PTR) WrPtr_dff (
.din (NxtWrPtr[DEPTH_PTR-1:0]),
.dout(WrPtr[DEPTH_PTR-1:0]),
.en (WrPtrEn),
.clk (dma_free_clk),
.*
);
rvdffs #(DEPTH_PTR) RdPtr_dff (
.din (NxtRdPtr[DEPTH_PTR-1:0]),
.dout(RdPtr[DEPTH_PTR-1:0]),
.en (RdPtrEn),
.clk (dma_free_clk),
.*
);
rvdffs #(DEPTH_PTR) RspPtr_dff (
.din (NxtRspPtr[DEPTH_PTR-1:0]),
.dout(RspPtr[DEPTH_PTR-1:0]),
.en (RspPtrEn),
.clk (dma_free_clk),
.*
);
// Miscellaneous signals
assign fifo_full = fifo_full_spec_bus;
@ -347,7 +465,13 @@ module el2_dma_ctrl #(
assign dma_nack_count_d[2:0] = (dma_nack_count[2:0] >= dma_nack_count_csr[2:0]) ? ({3{~(dma_dccm_req | dma_iccm_req)}} & dma_nack_count[2:0]) :
(dma_mem_req & ~(dma_dccm_req | dma_iccm_req)) ? (dma_nack_count[2:0] + 1'b1) : 3'b0;
rvdffs #(3) nack_count_dff(.din(dma_nack_count_d[2:0]), .dout(dma_nack_count[2:0]), .en(dma_mem_req), .clk(dma_free_clk), .*);
rvdffs #(3) nack_count_dff (
.din (dma_nack_count_d[2:0]),
.dout(dma_nack_count[2:0]),
.en (dma_mem_req),
.clk (dma_free_clk),
.*
);
// Core outputs
assign dma_mem_req = fifo_valid[RdPtr] & ~fifo_rpend[RdPtr] & ~fifo_done[RdPtr] & ~(dma_address_error | dma_alignment_error | dma_dbg_cmd_error);
@ -370,8 +494,10 @@ module el2_dma_ctrl #(
// Address check dccm
if (pt.DCCM_ENABLE) begin : Gen_dccm_enable
rvrangecheck #(.CCM_SADR(pt.DCCM_SADR),
.CCM_SIZE(pt.DCCM_SIZE)) addr_dccm_rangecheck (
rvrangecheck #(
.CCM_SADR(pt.DCCM_SADR),
.CCM_SIZE(pt.DCCM_SIZE)
) addr_dccm_rangecheck (
.addr(dma_mem_addr_int[31:0]),
.in_range(dma_mem_addr_in_dccm),
.in_region(dma_mem_addr_in_dccm_region_nc)
@ -383,8 +509,10 @@ module el2_dma_ctrl #(
// Address check iccm
if (pt.ICCM_ENABLE) begin : Gen_iccm_enable
rvrangecheck #(.CCM_SADR(pt.ICCM_SADR),
.CCM_SIZE(pt.ICCM_SIZE)) addr_iccm_rangecheck (
rvrangecheck #(
.CCM_SADR(pt.ICCM_SADR),
.CCM_SIZE(pt.ICCM_SIZE)
) addr_iccm_rangecheck (
.addr(dma_mem_addr_int[31:0]),
.in_range(dma_mem_addr_in_iccm),
.in_region(dma_mem_addr_in_iccm_region_nc)
@ -396,26 +524,59 @@ module el2_dma_ctrl #(
// PIC memory address check
rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR),
.CCM_SIZE(pt.PIC_SIZE)) addr_pic_rangecheck (
rvrangecheck #(
.CCM_SADR(pt.PIC_BASE_ADDR),
.CCM_SIZE(pt.PIC_SIZE)
) addr_pic_rangecheck (
.addr(dma_mem_addr_int[31:0]),
.in_range(dma_mem_addr_in_pic),
.in_region(dma_mem_addr_in_pic_region_nc)
);
// Inputs
rvdff_fpga #(1) fifo_full_bus_ff (.din(fifo_full_spec), .dout(fifo_full_spec_bus), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
rvdff_fpga #(1) dbg_dma_bubble_ff (.din(dbg_dma_bubble), .dout(dbg_dma_bubble_bus), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
rvdff #(1) dma_dbg_cmd_doneff (.din(dma_dbg_cmd_done), .dout(dma_dbg_cmd_done_q), .clk(free_clk), .*);
rvdff_fpga #(1) fifo_full_bus_ff (
.din(fifo_full_spec),
.dout(fifo_full_spec_bus),
.clk(dma_bus_clk),
.clken(dma_bus_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(1) dbg_dma_bubble_ff (
.din(dbg_dma_bubble),
.dout(dbg_dma_bubble_bus),
.clk(dma_bus_clk),
.clken(dma_bus_clk_en),
.rawclk(clk),
.*
);
rvdff #(1) dma_dbg_cmd_doneff (
.din (dma_dbg_cmd_done),
.dout(dma_dbg_cmd_done_q),
.clk (free_clk),
.*
);
// Clock Gating logic
assign dma_buffer_c1_clken = (bus_cmd_valid & dma_bus_clk_en) | dbg_cmd_valid | clk_override;
assign dma_free_clken = (bus_cmd_valid | bus_rsp_valid | dbg_cmd_valid | dma_dbg_cmd_done | dma_dbg_cmd_done_q | (|fifo_valid[DEPTH-1:0]) | clk_override);
rvoclkhdr dma_buffer_c1cgc ( .en(dma_buffer_c1_clken), .l1clk(dma_buffer_c1_clk), .* );
rvoclkhdr dma_free_cgc (.en(dma_free_clken), .l1clk(dma_free_clk), .*);
rvoclkhdr dma_buffer_c1cgc (
.en(dma_buffer_c1_clken),
.l1clk(dma_buffer_c1_clk),
.*
);
rvoclkhdr dma_free_cgc (
.en(dma_free_clken),
.l1clk(dma_free_clk),
.*
);
rvclkhdr dma_bus_cgc (.en(dma_bus_clk_en), .l1clk(dma_bus_clk), .*);
rvclkhdr dma_bus_cgc (
.en(dma_bus_clk_en),
.l1clk(dma_bus_clk),
.*
);
// Write channel buffer
assign wrbuf_en = dma_axi_awvalid & dma_axi_awready;
@ -424,23 +585,127 @@ module el2_dma_ctrl #(
assign wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en;
assign wrbuf_data_rst = wrbuf_cmd_sent & ~wrbuf_data_en;
rvdffsc_fpga #(.WIDTH(1)) wrbuf_vldff (.din(1'b1), .dout(wrbuf_vld), .en(wrbuf_en), .clear(wrbuf_rst), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
rvdffsc_fpga #(.WIDTH(1)) wrbuf_data_vldff (.din(1'b1), .dout(wrbuf_data_vld), .en(wrbuf_data_en), .clear(wrbuf_data_rst), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(pt.DMA_BUS_TAG)) wrbuf_tagff (.din(dma_axi_awid[pt.DMA_BUS_TAG-1:0]), .dout(wrbuf_tag[pt.DMA_BUS_TAG-1:0]), .en(wrbuf_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(3)) wrbuf_szff (.din(dma_axi_awsize[2:0]), .dout(wrbuf_sz[2:0]), .en(wrbuf_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
rvdffe #(.WIDTH(32)) wrbuf_addrff (.din(dma_axi_awaddr[31:0]), .dout(wrbuf_addr[31:0]), .en(wrbuf_en & dma_bus_clk_en), .*);
rvdffe #(.WIDTH(64)) wrbuf_dataff (.din(dma_axi_wdata[63:0]), .dout(wrbuf_data[63:0]), .en(wrbuf_data_en & dma_bus_clk_en), .*);
rvdffs_fpga #(.WIDTH(8)) wrbuf_byteenff (.din(dma_axi_wstrb[7:0]), .dout(wrbuf_byteen[7:0]), .en(wrbuf_data_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
rvdffsc_fpga #(
.WIDTH(1)
) wrbuf_vldff (
.din(1'b1),
.dout(wrbuf_vld),
.en(wrbuf_en),
.clear(wrbuf_rst),
.clk(dma_bus_clk),
.clken(dma_bus_clk_en),
.rawclk(clk),
.*
);
rvdffsc_fpga #(
.WIDTH(1)
) wrbuf_data_vldff (
.din(1'b1),
.dout(wrbuf_data_vld),
.en(wrbuf_data_en),
.clear(wrbuf_data_rst),
.clk(dma_bus_clk),
.clken(dma_bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(pt.DMA_BUS_TAG)
) wrbuf_tagff (
.din(dma_axi_awid[pt.DMA_BUS_TAG-1:0]),
.dout(wrbuf_tag[pt.DMA_BUS_TAG-1:0]),
.en(wrbuf_en),
.clk(dma_bus_clk),
.clken(dma_bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(3)
) wrbuf_szff (
.din(dma_axi_awsize[2:0]),
.dout(wrbuf_sz[2:0]),
.en(wrbuf_en),
.clk(dma_bus_clk),
.clken(dma_bus_clk_en),
.rawclk(clk),
.*
);
rvdffe #(
.WIDTH(32)
) wrbuf_addrff (
.din (dma_axi_awaddr[31:0]),
.dout(wrbuf_addr[31:0]),
.en (wrbuf_en & dma_bus_clk_en),
.*
);
rvdffe #(
.WIDTH(64)
) wrbuf_dataff (
.din (dma_axi_wdata[63:0]),
.dout(wrbuf_data[63:0]),
.en (wrbuf_data_en & dma_bus_clk_en),
.*
);
rvdffs_fpga #(
.WIDTH(8)
) wrbuf_byteenff (
.din(dma_axi_wstrb[7:0]),
.dout(wrbuf_byteen[7:0]),
.en(wrbuf_data_en),
.clk(dma_bus_clk),
.clken(dma_bus_clk_en),
.rawclk(clk),
.*
);
// Read channel buffer
assign rdbuf_en = dma_axi_arvalid & dma_axi_arready;
assign rdbuf_cmd_sent = bus_cmd_sent & ~bus_cmd_write;
assign rdbuf_rst = rdbuf_cmd_sent & ~rdbuf_en;
rvdffsc_fpga #(.WIDTH(1)) rdbuf_vldff (.din(1'b1), .dout(rdbuf_vld), .en(rdbuf_en), .clear(rdbuf_rst), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(pt.DMA_BUS_TAG)) rdbuf_tagff (.din(dma_axi_arid[pt.DMA_BUS_TAG-1:0]), .dout(rdbuf_tag[pt.DMA_BUS_TAG-1:0]), .en(rdbuf_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(3)) rdbuf_szff (.din(dma_axi_arsize[2:0]), .dout(rdbuf_sz[2:0]), .en(rdbuf_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
rvdffe #(.WIDTH(32)) rdbuf_addrff (.din(dma_axi_araddr[31:0]), .dout(rdbuf_addr[31:0]), .en(rdbuf_en & dma_bus_clk_en), .*);
rvdffsc_fpga #(
.WIDTH(1)
) rdbuf_vldff (
.din(1'b1),
.dout(rdbuf_vld),
.en(rdbuf_en),
.clear(rdbuf_rst),
.clk(dma_bus_clk),
.clken(dma_bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(pt.DMA_BUS_TAG)
) rdbuf_tagff (
.din(dma_axi_arid[pt.DMA_BUS_TAG-1:0]),
.dout(rdbuf_tag[pt.DMA_BUS_TAG-1:0]),
.en(rdbuf_en),
.clk(dma_bus_clk),
.clken(dma_bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(3)
) rdbuf_szff (
.din(dma_axi_arsize[2:0]),
.dout(rdbuf_sz[2:0]),
.en(rdbuf_en),
.clk(dma_bus_clk),
.clken(dma_bus_clk_en),
.rawclk(clk),
.*
);
rvdffe #(
.WIDTH(32)
) rdbuf_addrff (
.din (dma_axi_araddr[31:0]),
.dout(rdbuf_addr[31:0]),
.en (rdbuf_en & dma_bus_clk_en),
.*
);
assign dma_axi_awready = ~(wrbuf_vld & ~wrbuf_cmd_sent);
assign dma_axi_wready = ~(wrbuf_data_vld & ~wrbuf_cmd_sent);
@ -463,7 +728,17 @@ module el2_dma_ctrl #(
assign axi_mstr_sel = (wrbuf_vld & wrbuf_data_vld & rdbuf_vld) ? axi_mstr_priority : (wrbuf_vld & wrbuf_data_vld);
assign axi_mstr_prty_in = ~axi_mstr_priority;
assign axi_mstr_prty_en = bus_cmd_sent;
rvdffs_fpga #(.WIDTH(1)) mstr_prtyff(.din(axi_mstr_prty_in), .dout(axi_mstr_priority), .en(axi_mstr_prty_en), .clk(dma_bus_clk), .clken(dma_bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(
.WIDTH(1)
) mstr_prtyff (
.din(axi_mstr_prty_in),
.dout(axi_mstr_priority),
.en(axi_mstr_prty_en),
.clk(dma_bus_clk),
.clken(dma_bus_clk_en),
.rawclk(clk),
.*
);
assign axi_rsp_valid = fifo_valid[RspPtr] & ~fifo_dbg[RspPtr] & fifo_done_bus[RspPtr];
assign axi_rsp_rdata[63:0] = fifo_data[RspPtr];

View File

@ -19,8 +19,7 @@ module el2_mem
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk,
input logic rst_l,
input logic dccm_clk_override,
@ -95,11 +94,17 @@ import el2_pkg::*;
);
logic active_clk;
rvoclkhdr active_cg ( .en(1'b1), .l1clk(active_clk), .* );
rvoclkhdr active_cg (
.en(1'b1),
.l1clk(active_clk),
.*
);
// DCCM Instantiation
if (pt.DCCM_ENABLE == 1) begin : Gen_dccm_enable
el2_lsu_dccm_mem #(.pt(pt)) dccm (
el2_lsu_dccm_mem #(
.pt(pt)
) dccm (
.clk_override(dccm_clk_override),
.*
);
@ -109,12 +114,13 @@ import el2_pkg::*;
end
if (pt.ICACHE_ENABLE) begin : icache
el2_ifu_ic_mem #(.pt(pt)) icm (
el2_ifu_ic_mem #(
.pt(pt)
) icm (
.clk_override(icm_clk_override),
.*
);
end
else begin
end else begin
assign ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0] = '0;
assign ic_tag_perr = '0 ;
assign ic_rd_data = '0 ;
@ -124,13 +130,15 @@ end // else: !if( pt.ICACHE_ENABLE )
if (pt.ICCM_ENABLE) begin : iccm
el2_ifu_iccm_mem #(.pt(pt)) iccm (.*,
el2_ifu_iccm_mem #(
.pt(pt)
) iccm (
.*,
.clk_override(icm_clk_override),
.iccm_rw_addr(iccm_rw_addr[pt.ICCM_BITS-1:1]),
.iccm_rd_data(iccm_rd_data[63:0])
);
end
else begin
end else begin
assign iccm_rd_data = '0 ;
assign iccm_rd_data_ecc = '0 ;
end

View File

@ -22,8 +22,7 @@
module el2_pic_ctrl #(
`include "el2_param.vh"
)
(
) (
input logic clk, // Core clock
input logic free_clk, // free clock
@ -165,11 +164,31 @@ logic [pt.PIC_TOTAL_INT_PLUS1-1:0] extintsrc_req_gw;
assign gw_config_c1_clken = (waddr_config_gw_base_match & picm_wren_ff) | (raddr_config_gw_base_match & picm_rden_ff) | clk_override;
// C1 - 1 clock pulse for data
rvoclkhdr pic_addr_c1_cgc ( .en(pic_raddr_c1_clken), .l1clk(pic_raddr_c1_clk), .* );
rvoclkhdr pic_data_c1_cgc ( .en(pic_data_c1_clken), .l1clk(pic_data_c1_clk), .* );
rvoclkhdr pic_pri_c1_cgc ( .en(pic_pri_c1_clken), .l1clk(pic_pri_c1_clk), .* );
rvoclkhdr pic_int_c1_cgc ( .en(pic_int_c1_clken), .l1clk(pic_int_c1_clk), .* );
rvoclkhdr gw_config_c1_cgc ( .en(gw_config_c1_clken), .l1clk(gw_config_c1_clk), .* );
rvoclkhdr pic_addr_c1_cgc (
.en(pic_raddr_c1_clken),
.l1clk(pic_raddr_c1_clk),
.*
);
rvoclkhdr pic_data_c1_cgc (
.en(pic_data_c1_clken),
.l1clk(pic_data_c1_clk),
.*
);
rvoclkhdr pic_pri_c1_cgc (
.en(pic_pri_c1_clken),
.l1clk(pic_pri_c1_clk),
.*
);
rvoclkhdr pic_int_c1_cgc (
.en(pic_int_c1_clken),
.l1clk(pic_int_c1_clk),
.*
);
rvoclkhdr gw_config_c1_cgc (
.en(gw_config_c1_clken),
.l1clk(gw_config_c1_clk),
.*
);
// ------ end clock gating section ------------------------
@ -189,12 +208,42 @@ assign waddr_config_gw_base_match = (picm_waddr_ff[31:NUM_LEVELS+2] == EXT_INT
assign picm_bypass_ff = picm_rden_ff & picm_wren_ff & ( picm_raddr_ff[31:0] == picm_waddr_ff[31:0] ); // pic writes and reads to same address together
rvdff #(32) picm_radd_flop (.*, .din (picm_rdaddr), .dout(picm_raddr_ff), .clk(pic_raddr_c1_clk));
rvdff #(32) picm_wadd_flop (.*, .din (picm_wraddr), .dout(picm_waddr_ff), .clk(pic_data_c1_clk));
rvdff #(1) picm_wre_flop (.*, .din (picm_wren), .dout(picm_wren_ff), .clk(free_clk));
rvdff #(1) picm_rde_flop (.*, .din (picm_rden), .dout(picm_rden_ff), .clk(free_clk));
rvdff #(1) picm_mke_flop (.*, .din (picm_mken), .dout(picm_mken_ff), .clk(free_clk));
rvdff #(32) picm_dat_flop (.*, .din (picm_wr_data[31:0]), .dout(picm_wr_data_ff[31:0]), .clk(pic_data_c1_clk));
rvdff #(32) picm_radd_flop (
.*,
.din (picm_rdaddr),
.dout(picm_raddr_ff),
.clk (pic_raddr_c1_clk)
);
rvdff #(32) picm_wadd_flop (
.*,
.din (picm_wraddr),
.dout(picm_waddr_ff),
.clk (pic_data_c1_clk)
);
rvdff #(1) picm_wre_flop (
.*,
.din (picm_wren),
.dout(picm_wren_ff),
.clk (free_clk)
);
rvdff #(1) picm_rde_flop (
.*,
.din (picm_rden),
.dout(picm_rden_ff),
.clk (free_clk)
);
rvdff #(1) picm_mke_flop (
.*,
.din (picm_mken),
.dout(picm_mken_ff),
.clk (free_clk)
);
rvdff #(32) picm_dat_flop (
.*,
.din (picm_wr_data[31:0]),
.dout(picm_wr_data_ff[31:0]),
.clk (pic_data_c1_clk)
);
//rvsyncss #(pt.PIC_TOTAL_INT_PLUS1-1) sync_inst
//(
@ -226,9 +275,17 @@ wire grp_clk, grp_clken;
assign grp_clken = |intenable_clk_enable[(p==INT_ENABLE_GRPS?pt.PIC_TOTAL_INT_PLUS1-1:p*4+3) : p*4] | io_clk_override;
rvclkhdr intenable_c1_cgc( .en(grp_clken), .l1clk(grp_clk), .* );
rvclkhdr intenable_c1_cgc (
.en(grp_clken),
.l1clk(grp_clk),
.*
);
for(genvar i= (p==0 ? 1: 0); i< (p==INT_ENABLE_GRPS ? pt.PIC_TOTAL_INT_PLUS1-p*4 :4); i++) begin : GW
for (
genvar i = (p == 0 ? 1 : 0);
i < (p == INT_ENABLE_GRPS ? pt.PIC_TOTAL_INT_PLUS1 - p * 4 : 4);
i++
) begin : GW
el2_configurable_gw gw_inst (
.*,
.gw_clk(grp_clk),
@ -264,9 +321,27 @@ for (i=0; i<pt.PIC_TOTAL_INT_PLUS1 ; i++) begin : SETREG
assign gw_clear_reg_we[i] = addr_clear_gw_base_match & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff ;
rvdffs #(INTPRIORITY_BITS) intpriority_ff (.*, .en( intpriority_reg_we[i]), .din (picm_wr_data_ff[INTPRIORITY_BITS-1:0]), .dout(intpriority_reg[i]), .clk(pic_pri_c1_clk));
rvdffs #(1) intenable_ff (.*, .en( intenable_reg_we[i]), .din (picm_wr_data_ff[0]), .dout(intenable_reg[i]), .clk(pic_int_c1_clk));
rvdffs #(2) gw_config_ff (.*, .en( gw_config_reg_we[i]), .din (picm_wr_data_ff[1:0]), .dout(gw_config_reg[i]), .clk(gw_config_c1_clk));
rvdffs #(INTPRIORITY_BITS) intpriority_ff (
.*,
.en (intpriority_reg_we[i]),
.din (picm_wr_data_ff[INTPRIORITY_BITS-1:0]),
.dout(intpriority_reg[i]),
.clk (pic_pri_c1_clk)
);
rvdffs #(1) intenable_ff (
.*,
.en (intenable_reg_we[i]),
.din (picm_wr_data_ff[0]),
.dout(intenable_reg[i]),
.clk (pic_int_c1_clk)
);
rvdffs #(2) gw_config_ff (
.*,
.en (gw_config_reg_we[i]),
.din (picm_wr_data_ff[1:0]),
.dout(gw_config_reg[i]),
.clk (gw_config_c1_clk)
);
assign intenable_clk_enable[i] = gw_config_reg[i][1] | intenable_reg_we[i] | intenable_reg[i] | gw_clear_reg_we[i] ;
@ -338,14 +413,23 @@ if (pt.PIC_2CYCLE == 1) begin : genblock
logic [NUM_LEVELS:NUM_LEVELS/2] [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] [INTPRIORITY_BITS-1:0] levelx_intpend_w_prior_en;
logic [NUM_LEVELS:NUM_LEVELS/2] [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] [ID_BITS-1:0] levelx_intpend_id;
assign level_intpend_w_prior_en[0][pt.PIC_TOTAL_INT_PLUS1+2:0] = {4'b0,4'b0,4'b0,intpend_w_prior_en[pt.PIC_TOTAL_INT_PLUS1-1:0]} ;
assign level_intpend_id[0][pt.PIC_TOTAL_INT_PLUS1+2:0] = {8'b0,8'b0,8'b0,intpend_id[pt.PIC_TOTAL_INT_PLUS1-1:0]} ;
assign level_intpend_w_prior_en[0][pt.PIC_TOTAL_INT_PLUS1+2:0] = {
4'b0, 4'b0, 4'b0, intpend_w_prior_en[pt.PIC_TOTAL_INT_PLUS1-1:0]
};
assign level_intpend_id[0][pt.PIC_TOTAL_INT_PLUS1+2:0] = {
8'b0, 8'b0, 8'b0, intpend_id[pt.PIC_TOTAL_INT_PLUS1-1:0]
};
logic [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0] [INTPRIORITY_BITS-1:0] l2_intpend_w_prior_en_ff;
logic [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0][ID_BITS-1:0] l2_intpend_id_ff;
assign levelx_intpend_w_prior_en[NUM_LEVELS/2][(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] = {{1*INTPRIORITY_BITS{1'b0}},l2_intpend_w_prior_en_ff[(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0]} ;
assign levelx_intpend_id[NUM_LEVELS/2][(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] = {{1*ID_BITS{1'b1}},l2_intpend_id_ff[(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0]} ;
assign levelx_intpend_w_prior_en[NUM_LEVELS/2][(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] = {
{1 * INTPRIORITY_BITS{1'b0}},
l2_intpend_w_prior_en_ff[(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0]
};
assign levelx_intpend_id[NUM_LEVELS/2][(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] = {
{1 * ID_BITS{1'b1}}, l2_intpend_id_ff[(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0]
};
/// Do the prioritization of the interrupts here ////////////
for (l = 0; l < NUM_LEVELS / 2; l++) begin : TOP_LEVEL
for (m = 0; m <= (pt.PIC_TOTAL_INT_PLUS1) / (2 ** (l + 1)); m++) begin : COMPARE
@ -353,21 +437,34 @@ if (pt.PIC_2CYCLE == 1) begin : genblock
assign level_intpend_w_prior_en[l+1][m+1] = '0;
assign level_intpend_id[l+1][m+1] = '0;
end
el2_cmp_and_mux #(.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
el2_cmp_and_mux #(
.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)
) cmp_l1 (
.a_id(level_intpend_id[l][2*m]),
.a_priority(level_intpend_w_prior_en[l][2*m]),
.b_id(level_intpend_id[l][2*m+1]),
.b_priority(level_intpend_w_prior_en[l][2*m+1]),
.out_id(level_intpend_id[l+1][m]),
.out_priority(level_intpend_w_prior_en[l+1][m])) ;
.out_priority(level_intpend_w_prior_en[l+1][m])
);
end
end
for (i = 0; i <= pt.PIC_TOTAL_INT_PLUS1 / 2 ** (NUM_LEVELS / 2); i++) begin : MIDDLE_FLOPS
rvdff #(INTPRIORITY_BITS) level2_intpend_prior_reg (.*, .din (level_intpend_w_prior_en[NUM_LEVELS/2][i]), .dout(l2_intpend_w_prior_en_ff[i]), .clk(free_clk));
rvdff #(ID_BITS) level2_intpend_id_reg (.*, .din (level_intpend_id[NUM_LEVELS/2][i]), .dout(l2_intpend_id_ff[i]), .clk(free_clk));
rvdff #(INTPRIORITY_BITS) level2_intpend_prior_reg (
.*,
.din (level_intpend_w_prior_en[NUM_LEVELS/2][i]),
.dout(l2_intpend_w_prior_en_ff[i]),
.clk (free_clk)
);
rvdff #(ID_BITS) level2_intpend_id_reg (
.*,
.din (level_intpend_id[NUM_LEVELS/2][i]),
.dout(l2_intpend_id_ff[i]),
.clk (free_clk)
);
end
for (j = NUM_LEVELS / 2; j < NUM_LEVELS; j++) begin : BOT_LEVELS
@ -376,27 +473,32 @@ if (pt.PIC_2CYCLE == 1) begin : genblock
assign levelx_intpend_w_prior_en[j+1][k+1] = '0;
assign levelx_intpend_id[j+1][k+1] = '0;
end
el2_cmp_and_mux #(.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS))
cmp_l1 (
el2_cmp_and_mux #(
.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)
) cmp_l1 (
.a_id(levelx_intpend_id[j][2*k]),
.a_priority(levelx_intpend_w_prior_en[j][2*k]),
.b_id(levelx_intpend_id[j][2*k+1]),
.b_priority(levelx_intpend_w_prior_en[j][2*k+1]),
.out_id(levelx_intpend_id[j+1][k]),
.out_priority(levelx_intpend_w_prior_en[j+1][k])) ;
.out_priority(levelx_intpend_w_prior_en[j+1][k])
);
end
end
assign claimid_in[ID_BITS-1:0] = levelx_intpend_id[NUM_LEVELS][0] ; // This is the last level output
assign selected_int_priority[INTPRIORITY_BITS-1:0] = levelx_intpend_w_prior_en[NUM_LEVELS][0];
end
else begin : genblock
end else begin : genblock
logic [NUM_LEVELS:0] [pt.PIC_TOTAL_INT_PLUS1+1:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
logic [NUM_LEVELS:0][pt.PIC_TOTAL_INT_PLUS1+1:0][ID_BITS-1:0] level_intpend_id;
assign level_intpend_w_prior_en[0][pt.PIC_TOTAL_INT_PLUS1+1:0] = {{2*INTPRIORITY_BITS{1'b0}},intpend_w_prior_en[pt.PIC_TOTAL_INT_PLUS1-1:0]} ;
assign level_intpend_id[0][pt.PIC_TOTAL_INT_PLUS1+1:0] = {{2*ID_BITS{1'b1}},intpend_id[pt.PIC_TOTAL_INT_PLUS1-1:0]} ;
assign level_intpend_w_prior_en[0][pt.PIC_TOTAL_INT_PLUS1+1:0] = {
{2 * INTPRIORITY_BITS{1'b0}}, intpend_w_prior_en[pt.PIC_TOTAL_INT_PLUS1-1:0]
};
assign level_intpend_id[0][pt.PIC_TOTAL_INT_PLUS1+1:0] = {
{2 * ID_BITS{1'b1}}, intpend_id[pt.PIC_TOTAL_INT_PLUS1-1:0]
};
/// Do the prioritization of the interrupts here ////////////
// genvar l, m , j, k; already declared outside ifdef
@ -406,14 +508,17 @@ else begin : genblock
assign level_intpend_w_prior_en[l+1][m+1] = '0;
assign level_intpend_id[l+1][m+1] = '0;
end
el2_cmp_and_mux #(.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
el2_cmp_and_mux #(
.ID_BITS(ID_BITS),
.INTPRIORITY_BITS(INTPRIORITY_BITS)
) cmp_l1 (
.a_id(level_intpend_id[l][2*m]),
.a_priority(level_intpend_w_prior_en[l][2*m]),
.b_id(level_intpend_id[l][2*m+1]),
.b_priority(level_intpend_w_prior_en[l][2*m+1]),
.out_id(level_intpend_id[l+1][m]),
.out_priority(level_intpend_w_prior_en[l+1][m])) ;
.out_priority(level_intpend_w_prior_en[l+1][m])
);
end
end
@ -431,7 +536,13 @@ assign config_reg_we = waddr_config_pic_match & picm_wren_ff;
assign config_reg_re = raddr_config_pic_match & picm_rden_ff;
assign config_reg_in = picm_wr_data_ff[0]; //
rvdffs #(1) config_reg_ff (.*, .clk(free_clk), .en(config_reg_we), .din (config_reg_in), .dout(config_reg));
rvdffs #(1) config_reg_ff (
.*,
.clk (free_clk),
.en (config_reg_we),
.din (config_reg_in),
.dout(config_reg)
);
assign intpriord = config_reg;
@ -445,19 +556,39 @@ assign intpriord = config_reg ;
///////////////////////////////////////////////////////////
//
assign pl_in_q[INTPRIORITY_BITS-1:0] = intpriord ? ~pl_in : pl_in;
rvdff #(ID_BITS) claimid_ff (.*, .din (claimid_in[ID_BITS-1:00]), .dout(claimid[ID_BITS-1:00]), .clk(free_clk));
rvdff #(INTPRIORITY_BITS) pl_ff (.*, .din (pl_in_q[INTPRIORITY_BITS-1:0]), .dout(pl[INTPRIORITY_BITS-1:0]), .clk(free_clk));
rvdff #(ID_BITS) claimid_ff (
.*,
.din (claimid_in[ID_BITS-1:00]),
.dout(claimid[ID_BITS-1:00]),
.clk (free_clk)
);
rvdff #(INTPRIORITY_BITS) pl_ff (
.*,
.din (pl_in_q[INTPRIORITY_BITS-1:0]),
.dout(pl[INTPRIORITY_BITS-1:0]),
.clk (free_clk)
);
logic [INTPRIORITY_BITS-1:0] meipt_inv, meicurpl_inv;
assign meipt_inv[INTPRIORITY_BITS-1:0] = intpriord ? ~meipt[INTPRIORITY_BITS-1:0] : meipt[INTPRIORITY_BITS-1:0] ;
assign meicurpl_inv[INTPRIORITY_BITS-1:0] = intpriord ? ~meicurpl[INTPRIORITY_BITS-1:0] : meicurpl[INTPRIORITY_BITS-1:0] ;
assign mexintpend_in = (( selected_int_priority[INTPRIORITY_BITS-1:0] > meipt_inv[INTPRIORITY_BITS-1:0]) &
( selected_int_priority[INTPRIORITY_BITS-1:0] > meicurpl_inv[INTPRIORITY_BITS-1:0]) );
rvdff #(1) mexintpend_ff (.*, .clk(free_clk), .din (mexintpend_in), .dout(mexintpend));
rvdff #(1) mexintpend_ff (
.*,
.clk (free_clk),
.din (mexintpend_in),
.dout(mexintpend)
);
assign maxint[INTPRIORITY_BITS-1:0] = intpriord ? 0 : 15;
assign mhwakeup_in = (pl_in_q[INTPRIORITY_BITS-1:0] == maxint);
rvdff #(1) wake_up_ff (.*, .clk(free_clk), .din (mhwakeup_in), .dout(mhwakeup));
rvdff #(1) wake_up_ff (
.*,
.clk (free_clk),
.din (mhwakeup_in),
.dout(mhwakeup)
);
@ -473,7 +604,9 @@ assign intpriority_reg_read = raddr_intpriority_base_match & picm_rden_ff;
assign intenable_reg_read = raddr_intenable_base_match & picm_rden_ff;
assign gw_config_reg_read = raddr_config_gw_base_match & picm_rden_ff;
assign intpend_reg_extended[INTPEND_SIZE-1:0] = {{INTPEND_SIZE-pt.PIC_TOTAL_INT_PLUS1{1'b0}},extintsrc_req_gw[pt.PIC_TOTAL_INT_PLUS1-1:0]} ;
assign intpend_reg_extended[INTPEND_SIZE-1:0] = {
{INTPEND_SIZE - pt.PIC_TOTAL_INT_PLUS1{1'b0}}, extintsrc_req_gw[pt.PIC_TOTAL_INT_PLUS1-1:0]
};
for (i = 0; i < (INT_GRPS); i++) begin
assign intpend_rd_part_out[i] = (({32{intpend_reg_read & picm_raddr_ff[5:2] == i}}) & intpend_reg_extended[((32*i)+31):(32*i)]) ;
@ -526,9 +659,10 @@ assign address[14:0] = picm_raddr_ff[14:0];
endmodule
module el2_cmp_and_mux #(parameter ID_BITS=8,
INTPRIORITY_BITS = 4)
(
module el2_cmp_and_mux #(
parameter ID_BITS = 8,
INTPRIORITY_BITS = 4
) (
input logic [ ID_BITS-1:0] a_id,
input logic [INTPRIORITY_BITS-1:0] a_priority,
@ -544,8 +678,7 @@ logic a_is_lt_b ;
assign a_is_lt_b = (a_priority[INTPRIORITY_BITS-1:0] < b_priority[INTPRIORITY_BITS-1:0]);
assign out_id[ID_BITS-1:0] = a_is_lt_b ? b_id[ID_BITS-1:0] :
a_id[ID_BITS-1:0] ;
assign out_id[ID_BITS-1:0] = a_is_lt_b ? b_id[ID_BITS-1:0] : a_id[ID_BITS-1:0];
assign out_priority[INTPRIORITY_BITS-1:0] = a_is_lt_b ? b_priority[INTPRIORITY_BITS-1:0] :
a_priority[INTPRIORITY_BITS-1:0] ;
endmodule // cmp_and_mux
@ -570,11 +703,19 @@ module el2_configurable_gw (
rvsyncss_fpga #(1) sync_inst (
.dout(extintsrc_req_sync),
.din (extintsrc_req),
.*) ;
.*
);
assign gw_int_pending_in = (extintsrc_req_sync ^ meigwctrl_polarity) | (gw_int_pending & ~meigwclr) ;
rvdff_fpga #(1) int_pend_ff (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (gw_int_pending_in), .dout(gw_int_pending));
rvdff_fpga #(1) int_pend_ff (
.*,
.clk(gw_clk),
.rawclk(rawclk),
.clken(clken),
.din(gw_int_pending_in),
.dout(gw_int_pending)
);
assign extintsrc_req_config = meigwctrl_type ? ((extintsrc_req_sync ^ meigwctrl_polarity) | gw_int_pending) : (extintsrc_req_sync ^ meigwctrl_polarity) ;

View File

@ -24,8 +24,7 @@ module el2_swerv
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk,
input logic rst_l,
input logic dbg_rst_l,
@ -820,19 +819,41 @@ import el2_pkg::*;
assign active_state = (~(halt_state | pause_state) | dec_tlu_flush_lower_r | dec_tlu_flush_lower_wb) | dec_tlu_misc_clk_override;
rvoclkhdr free_cg2 ( .clk(clk), .en(1'b1), .l1clk(free_l2clk), .* );
rvoclkhdr active_cg2 ( .clk(clk), .en(active_state), .l1clk(active_l2clk), .* );
rvoclkhdr free_cg2 (
.clk(clk),
.en(1'b1),
.l1clk(free_l2clk),
.*
);
rvoclkhdr active_cg2 (
.clk(clk),
.en(active_state),
.l1clk(active_l2clk),
.*
);
// all other clock headers are 1st level
rvoclkhdr free_cg1 ( .clk(free_l2clk), .en(1'b1), .l1clk(free_clk), .* );
rvoclkhdr active_cg1 ( .clk(active_l2clk), .en(1'b1), .l1clk(active_clk), .* );
rvoclkhdr free_cg1 (
.clk(free_l2clk),
.en(1'b1),
.l1clk(free_clk),
.*
);
rvoclkhdr active_cg1 (
.clk(active_l2clk),
.en(1'b1),
.l1clk(active_clk),
.*
);
assign core_dbg_cmd_done = dma_dbg_cmd_done | dec_dbg_cmd_done;
assign core_dbg_cmd_fail = dma_dbg_cmd_fail | dec_dbg_cmd_fail;
assign core_dbg_rddata[31:0] = dma_dbg_cmd_done ? dma_dbg_rddata[31:0] : dec_dbg_rddata[31:0];
el2_dbg #(.pt(pt)) dbg (
el2_dbg #(
.pt(pt)
) dbg (
.rst_l(core_rst_l),
.clk(free_l2clk),
.clk_override(dec_tlu_misc_clk_override),
@ -854,7 +875,9 @@ import el2_pkg::*;
assign core_rst_l = rst_l & (dbg_core_rst_l | scan_mode);
// fetch
el2_ifu #(.pt(pt)) ifu (
el2_ifu #(
.pt(pt)
) ifu (
.clk (active_l2clk),
.rst_l (core_rst_l),
.dec_tlu_flush_err_wb (dec_tlu_flush_err_r),
@ -874,20 +897,26 @@ import el2_pkg::*;
);
el2_dec #(.pt(pt)) dec (
el2_dec #(
.pt(pt)
) dec (
.clk(active_l2clk),
.dbg_cmd_wrdata(dbg_cmd_wrdata[1:0]),
.rst_l(core_rst_l),
.*
);
el2_exu #(.pt(pt)) exu (
el2_exu #(
.pt(pt)
) exu (
.clk (active_l2clk),
.rst_l(core_rst_l),
.*
);
el2_lsu #(.pt(pt)) lsu (
el2_lsu #(
.pt(pt)
) lsu (
.clk(active_l2clk),
.rst_l(core_rst_l),
.clk_override(dec_tlu_lsu_clk_override),
@ -912,7 +941,9 @@ import el2_pkg::*;
);
el2_pic_ctrl #(.pt(pt)) pic_ctrl_inst (
el2_pic_ctrl #(
.pt(pt)
) pic_ctrl_inst (
.clk(free_l2clk),
.clk_override(dec_tlu_pic_clk_override),
.io_clk_override(dec_tlu_picio_clk_override),
@ -923,9 +954,12 @@ import el2_pkg::*;
.meicurpl(dec_tlu_meicurpl[3:0]),
.meipt(dec_tlu_meipt[3:0]),
.rst_l(core_rst_l),
.*);
.*
);
el2_dma_ctrl #(.pt(pt)) dma_ctrl (
el2_dma_ctrl #(
.pt(pt)
) dma_ctrl (
.clk(free_l2clk),
.rst_l(core_rst_l),
.clk_override(dec_tlu_misc_clk_override),
@ -952,8 +986,10 @@ import el2_pkg::*;
if (pt.BUILD_AHB_LITE == 1) begin : Gen_AXI_To_AHB
// AXI4 -> AHB Gasket for LSU
axi4_to_ahb #(.pt(pt),
.TAG(pt.LSU_BUS_TAG)) lsu_axi4_to_ahb (
axi4_to_ahb #(
.pt (pt),
.TAG(pt.LSU_BUS_TAG)
) lsu_axi4_to_ahb (
.clk(free_l2clk),
.free_clk(free_clk),
@ -1013,8 +1049,10 @@ import el2_pkg::*;
.*
);
axi4_to_ahb #(.pt(pt),
.TAG(pt.IFU_BUS_TAG)) ifu_axi4_to_ahb (
axi4_to_ahb #(
.pt (pt),
.TAG(pt.IFU_BUS_TAG)
) ifu_axi4_to_ahb (
.clk(free_l2clk),
.free_clk(free_clk),
.rst_l(core_rst_l),
@ -1073,8 +1111,10 @@ import el2_pkg::*;
);
// AXI4 -> AHB Gasket for System Bus
axi4_to_ahb #(.pt(pt),
.TAG(pt.SB_BUS_TAG)) sb_axi4_to_ahb (
axi4_to_ahb #(
.pt (pt),
.TAG(pt.SB_BUS_TAG)
) sb_axi4_to_ahb (
.clk(free_l2clk),
.free_clk(free_clk),
.rst_l(dbg_rst_l),
@ -1133,8 +1173,10 @@ import el2_pkg::*;
);
//AHB -> AXI4 Gasket for DMA
ahb_to_axi4 #(.pt(pt),
.TAG(pt.DMA_BUS_TAG)) dma_ahb_to_axi4 (
ahb_to_axi4 #(
.pt (pt),
.TAG(pt.DMA_BUS_TAG)
) dma_ahb_to_axi4 (
.clk(free_l2clk),
.rst_l(core_rst_l),
.clk_override(dec_tlu_bus_clk_override),

View File

@ -24,8 +24,7 @@ module el2_swerv_wrapper
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk,
input logic rst_l,
input logic dbg_rst_l,
@ -685,13 +684,17 @@ import el2_pkg::*;
logic [31:0] dmi_reg_rdata;
// Instantiate the el2_swerv core
el2_swerv #(.pt(pt)) swerv (
el2_swerv #(
.pt(pt)
) swerv (
.clk(clk),
.*
);
// Instantiate the mem
el2_mem #(.pt(pt)) mem (
el2_mem #(
.pt(pt)
) mem (
.clk (active_l2clk),
.rst_l(core_rst_l),
.*

View File

@ -18,8 +18,7 @@ module el2_exu
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk, // Top level clock
input logic rst_l, // Reset
input logic scan_mode, // Scan control
@ -157,30 +156,101 @@ import el2_pkg::*;
rvdffpcie #(31) i_flush_path_x_ff (.*, .clk(clk), .en ( x_data_en ), .din ( i0_flush_path_d[31:1] ), .dout( i0_flush_path_x[31:1] ) );
rvdffe #(32) i_csr_rs1_x_ff (.*, .clk(clk), .en ( x_data_en_q1 ), .din ( i0_rs1_d[31:0] ), .dout( exu_csr_rs1_x[31:0] ) );
rvdffppe #($bits(el2_predict_pkt_t)) i_predictpacket_x_ff (.*, .clk(clk), .en ( x_data_en ), .din ( i0_predict_p_d ), .dout( i0_predict_p_x ) );
rvdffe #(PREDPIPESIZE) i_predpipe_x_ff (.*, .clk(clk), .en ( x_data_en_q2 ), .din ( predpipe_d ), .dout( predpipe_x ) );
rvdffe #(PREDPIPESIZE) i_predpipe_r_ff (.*, .clk(clk), .en ( r_data_en_q2 ), .din ( predpipe_x ), .dout( predpipe_r ) );
rvdffpcie #(31) i_flush_path_x_ff (
.*,
.clk (clk),
.en (x_data_en),
.din (i0_flush_path_d[31:1]),
.dout(i0_flush_path_x[31:1])
);
rvdffe #(32) i_csr_rs1_x_ff (
.*,
.clk (clk),
.en (x_data_en_q1),
.din (i0_rs1_d[31:0]),
.dout(exu_csr_rs1_x[31:0])
);
rvdffppe #($bits(
el2_predict_pkt_t
)) i_predictpacket_x_ff (
.*,
.clk (clk),
.en (x_data_en),
.din (i0_predict_p_d),
.dout(i0_predict_p_x)
);
rvdffe #(PREDPIPESIZE) i_predpipe_x_ff (
.*,
.clk (clk),
.en (x_data_en_q2),
.din (predpipe_d),
.dout(predpipe_x)
);
rvdffe #(PREDPIPESIZE) i_predpipe_r_ff (
.*,
.clk (clk),
.en (r_data_en_q2),
.din (predpipe_x),
.dout(predpipe_r)
);
rvdffe #(4+pt.BHT_GHR_SIZE) i_x_ff (.*, .clk(clk), .en ( x_ctl_en ), .din ({i0_valid_d,i0_taken_d,i0_flush_upper_d,i0_pred_correct_upper_d,ghr_x_ns[pt.BHT_GHR_SIZE-1:0]} ),
.dout({i0_valid_x,i0_taken_x,i0_flush_upper_x,i0_pred_correct_upper_x,ghr_x[pt.BHT_GHR_SIZE-1:0]} ) );
rvdffe #(4 + pt.BHT_GHR_SIZE) i_x_ff (
.*,
.clk(clk),
.en(x_ctl_en),
.din({
i0_valid_d,
i0_taken_d,
i0_flush_upper_d,
i0_pred_correct_upper_d,
ghr_x_ns[pt.BHT_GHR_SIZE-1:0]
}),
.dout({
i0_valid_x,
i0_taken_x,
i0_flush_upper_x,
i0_pred_correct_upper_x,
ghr_x[pt.BHT_GHR_SIZE-1:0]
})
);
rvdffppe #($bits(el2_predict_pkt_t)+1) i_r_ff0 (.*, .clk(clk), .en ( r_ctl_en ), .din ({i0_pred_correct_upper_x, i0_predict_p_x}),
.dout({i0_pred_correct_upper_r, i0_pp_r }) );
rvdffppe #($bits(
el2_predict_pkt_t
) + 1) i_r_ff0 (
.*,
.clk (clk),
.en (r_ctl_en),
.din ({i0_pred_correct_upper_x, i0_predict_p_x}),
.dout({i0_pred_correct_upper_r, i0_pp_r})
);
rvdffpcie #(31) i_flush_r_ff (.*, .clk(clk), .en ( r_data_en ), .din ( i0_flush_path_x[31:1] ), .dout( i0_flush_path_upper_r[31:1]) );
rvdffpcie #(31) i_npc_r_ff (.*, .clk(clk), .en ( r_data_en ), .din ( pred_correct_npc_x[31:1] ), .dout( pred_correct_npc_r[31:1] ) );
rvdffpcie #(31) i_flush_r_ff (
.*,
.clk (clk),
.en (r_data_en),
.din (i0_flush_path_x[31:1]),
.dout(i0_flush_path_upper_r[31:1])
);
rvdffpcie #(31) i_npc_r_ff (
.*,
.clk (clk),
.en (r_data_en),
.din (pred_correct_npc_x[31:1]),
.dout(pred_correct_npc_r[31:1])
);
rvdffie #(pt.BHT_GHR_SIZE+2,1) i_misc_ff (.*, .clk(clk), .din ({ghr_d_ns[pt.BHT_GHR_SIZE-1:0], mul_p.valid, dec_i0_branch_d}),
.dout({ghr_d[pt.BHT_GHR_SIZE-1:0] , mul_valid_x, i0_branch_x}) );
rvdffie #(pt.BHT_GHR_SIZE + 2, 1) i_misc_ff (
.*,
.clk (clk),
.din ({ghr_d_ns[pt.BHT_GHR_SIZE-1:0], mul_p.valid, dec_i0_branch_d}),
.dout({ghr_d[pt.BHT_GHR_SIZE-1:0], mul_valid_x, i0_branch_x})
);
assign predpipe_d[PREDPIPESIZE-1:0]
= {i0_predict_fghr_d, i0_predict_index_d, i0_predict_btag_d};
assign predpipe_d[PREDPIPESIZE-1:0] = {i0_predict_fghr_d, i0_predict_index_d, i0_predict_btag_d};
assign i0_rs1_bypass_en_d = dec_i0_rs1_bypass_en_d[0] | dec_i0_rs1_bypass_en_d[1] | dec_i0_rs1_bypass_en_d[2] | dec_i0_rs1_bypass_en_d[3];
@ -230,7 +300,10 @@ import el2_pkg::*;
el2_exu_alu_ctl #(.pt(pt)) i_alu (.*,
el2_exu_alu_ctl #(
.pt(pt)
) i_alu (
.*,
.enable (x_data_en), // I
.pp_in (i0_predict_newp_d), // I
.valid_in (dec_i0_alu_decode_d), // I
@ -249,25 +322,34 @@ import el2_pkg::*;
.flush_path_out (i0_flush_path_d[31:1]), // O
.predict_p_out (i0_predict_p_d), // O
.pred_correct_out(i0_pred_correct_upper_d), // O
.pc_ff ( exu_i0_pc_x[31:1] )); // O
.pc_ff (exu_i0_pc_x[31:1])
); // O
el2_exu_mul_ctl #(.pt(pt)) i_mul (.*,
el2_exu_mul_ctl #(
.pt(pt)
) i_mul (
.*,
.mul_p (mul_p & {$bits(el2_mul_pkt_t) {mul_p.valid}}), // I
.rs1_in (muldiv_rs1_d[31:0] & {32{mul_p.valid}}), // I
.rs2_in (i0_rs2_d[31:0] & {32{mul_p.valid}}), // I
.result_x ( mul_result_x[31:0] )); // O
.result_x(mul_result_x[31:0])
); // O
el2_exu_div_ctl #(.pt(pt)) i_div (.*,
el2_exu_div_ctl #(
.pt(pt)
) i_div (
.*,
.cancel (dec_div_cancel), // I
.dp (div_p), // I
.dividend (muldiv_rs1_d[31:0]), // I
.divisor (i0_rs2_d[31:0]), // I
.finish_dly(exu_div_wren), // O
.out ( exu_div_result[31:0] )); // O
.out (exu_div_result[31:0])
); // O

View File

@ -18,8 +18,7 @@ module el2_exu_alu_ctl
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk, // Top level clock
input logic rst_l, // Reset
input logic scan_mode, // Scan control
@ -105,8 +104,7 @@ import el2_pkg::*;
if (pt.BITMANIP_ZBB == 1)
begin
if (pt.BITMANIP_ZBB == 1) begin
assign ap_clz = ap.clz;
assign ap_ctz = ap.ctz;
assign ap_cpop = ap.cpop;
@ -114,9 +112,7 @@ import el2_pkg::*;
assign ap_sext_h = ap.sext_h;
assign ap_min = ap.min;
assign ap_max = ap.max;
end
else
begin
end else begin
assign ap_clz = 1'b0;
assign ap_ctz = 1'b0;
assign ap_cpop = 1'b0;
@ -127,16 +123,13 @@ import el2_pkg::*;
end
if ( (pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1) )
begin
if ((pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1)) begin
assign ap_rol = ap.rol;
assign ap_ror = ap.ror;
assign ap_rev8 = ap.grev & (b_in[4:0] == 5'b11000);
assign ap_orc_b = ap.gorc & (b_in[4:0] == 5'b00111);
assign ap_zbb = ap.zbb;
end
else
begin
end else begin
assign ap_rol = 1'b0;
assign ap_ror = 1'b0;
assign ap_rev8 = 1'b0;
@ -145,15 +138,12 @@ import el2_pkg::*;
end
if (pt.BITMANIP_ZBS == 1)
begin
if (pt.BITMANIP_ZBS == 1) begin
assign ap_bset = ap.bset;
assign ap_bclr = ap.bclr;
assign ap_binv = ap.binv;
assign ap_bext = ap.bext;
end
else
begin
end else begin
assign ap_bset = 1'b0;
assign ap_bclr = 1'b0;
assign ap_binv = 1'b0;
@ -161,12 +151,9 @@ import el2_pkg::*;
end
if (pt.BITMANIP_ZBP == 1)
begin
if (pt.BITMANIP_ZBP == 1) begin
assign ap_packu = ap.packu;
end
else
begin
end else begin
assign ap_packu = 1'b0;
end
@ -175,23 +162,18 @@ import el2_pkg::*;
begin
assign ap_pack = ap.pack;
assign ap_packh = ap.packh;
end
else
begin
end else begin
assign ap_pack = 1'b0;
assign ap_packh = 1'b0;
end
if (pt.BITMANIP_ZBA == 1)
begin
if (pt.BITMANIP_ZBA == 1) begin
assign ap_sh1add = ap.sh1add;
assign ap_sh2add = ap.sh2add;
assign ap_sh3add = ap.sh3add;
assign ap_zba = ap.zba;
end
else
begin
end else begin
assign ap_sh1add = 1'b0;
assign ap_sh2add = 1'b0;
assign ap_sh3add = 1'b0;
@ -206,8 +188,20 @@ import el2_pkg::*;
rvdffpcie #(31) i_pc_ff (.*, .clk(clk), .en(enable), .din(pc_in[31:1]), .dout(pc_ff[31:1])); // any PC is run through here - doesn't have to be alu
rvdffe #(32) i_result_ff (.*, .clk(clk), .en(enable & valid_in), .din(result[31:0]), .dout(result_ff[31:0]));
rvdffpcie #(31) i_pc_ff (
.*,
.clk (clk),
.en (enable),
.din (pc_in[31:1]),
.dout(pc_ff[31:1])
); // any PC is run through here - doesn't have to be alu
rvdffe #(32) i_result_ff (
.*,
.clk (clk),
.en (enable & valid_in),
.din (result[31:0]),
.dout(result_ff[31:0])
);
@ -250,11 +244,9 @@ import el2_pkg::*;
assign {cout, aout[31:0]} = {1'b0, zba_a_in[31:0]} + {1'b0, bm[31:0]} + {32'b0, ap.sub};
assign ov = (~a_in[31] & ~bm[31] & aout[31]) |
( a_in[31] & bm[31] & ~aout[31] );
assign ov = (~a_in[31] & ~bm[31] & aout[31]) | (a_in[31] & bm[31] & ~aout[31]);
assign lt = (~ap.unsign & (neg ^ ov)) |
( ap.unsign & ~cout);
assign lt = (~ap.unsign & (neg ^ ov)) | (ap.unsign & ~cout);
assign eq = (a_in[31:0] == b_in[31:0]);
assign ne = ~eq;
@ -319,10 +311,40 @@ import el2_pkg::*;
assign bitmanip_clz_ctz_sel = ap_clz | ap_ctz;
assign bitmanip_a_reverse_ff[31:0] = {a_in[0], a_in[1], a_in[2], a_in[3], a_in[4], a_in[5], a_in[6], a_in[7],
a_in[8], a_in[9], a_in[10], a_in[11], a_in[12], a_in[13], a_in[14], a_in[15],
a_in[16], a_in[17], a_in[18], a_in[19], a_in[20], a_in[21], a_in[22], a_in[23],
a_in[24], a_in[25], a_in[26], a_in[27], a_in[28], a_in[29], a_in[30], a_in[31]};
assign bitmanip_a_reverse_ff[31:0] = {
a_in[0],
a_in[1],
a_in[2],
a_in[3],
a_in[4],
a_in[5],
a_in[6],
a_in[7],
a_in[8],
a_in[9],
a_in[10],
a_in[11],
a_in[12],
a_in[13],
a_in[14],
a_in[15],
a_in[16],
a_in[17],
a_in[18],
a_in[19],
a_in[20],
a_in[21],
a_in[22],
a_in[23],
a_in[24],
a_in[25],
a_in[26],
a_in[27],
a_in[28],
a_in[29],
a_in[30],
a_in[31]
};
assign bitmanip_lzd_in[31:0] = ( {32{ap_clz}} & a_in[31:0] ) |
( {32{ap_ctz}} & bitmanip_a_reverse_ff[31:0]);
@ -331,8 +353,7 @@ import el2_pkg::*;
integer i;
logic found;
always_comb
begin
always_comb begin
bitmanip_lzd_os[31:0] = bitmanip_lzd_in[31:0];
bitmanip_dw_lzd_enc[5:0] = 6'b0;
found = 1'b0;
@ -341,9 +362,7 @@ import el2_pkg::*;
if (bitmanip_lzd_os[31] == 1'b0) begin
bitmanip_dw_lzd_enc[5:0] = bitmanip_dw_lzd_enc[5:0] + 6'b00_0001;
bitmanip_lzd_os[31:0] = bitmanip_lzd_os[31:0] << 1;
end
else
found=1'b1;
end else found = 1'b1;
end
end
@ -362,12 +381,10 @@ import el2_pkg::*;
integer bitmanip_cpop_i;
always_comb
begin
always_comb begin
bitmanip_cpop[5:0] = 6'b0;
for (bitmanip_cpop_i=0; bitmanip_cpop_i<32; bitmanip_cpop_i++)
begin
for (bitmanip_cpop_i = 0; bitmanip_cpop_i < 32; bitmanip_cpop_i++) begin
bitmanip_cpop[5:0] = bitmanip_cpop[5:0] + {5'b0, a_in[bitmanip_cpop_i]};
end // FOR bitmanip_cpop_i
end // ALWAYS_COMB
@ -498,16 +515,9 @@ import el2_pkg::*;
// *** branch handling ***
assign any_jal = ap.jal |
pp_in.pcall |
pp_in.pja |
pp_in.pret;
assign any_jal = ap.jal | pp_in.pcall | pp_in.pja | pp_in.pret;
assign actual_taken = (ap.beq & eq) |
(ap.bne & ne) |
(ap.blt & lt) |
(ap.bge & ge) |
any_jal;
assign actual_taken = (ap.beq & eq) | (ap.bne & ne) | (ap.blt & lt) | (ap.bge & ge) | any_jal;
// for a conditional br pcout[] will be the opposite of the branch prediction
// for jal or pcall, it will be the link address pc+2 or pc+4
@ -515,7 +525,8 @@ import el2_pkg::*;
rvbradder ibradder (
.pc (pc_in[31:1]),
.offset(brimm_in[12:1]),
.dout ( pcout[31:1] ));
.dout (pcout[31:1])
);
// pred_correct is for the npc logic
@ -531,8 +542,7 @@ import el2_pkg::*;
// pcall and pret are included here
assign cond_mispredict = (ap.predict_t & ~actual_taken) |
(ap.predict_nt & actual_taken);
assign cond_mispredict = (ap.predict_t & ~actual_taken) | (ap.predict_nt & actual_taken);
// target mispredicts on ret's

View File

@ -18,8 +18,7 @@ module el2_exu_div_ctl
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk, // Top level clock
input logic rst_l, // Reset
input logic scan_mode, // Scan mode
@ -42,8 +41,7 @@ import el2_pkg::*;
if (pt.DIV_NEW == 0)
begin
if (pt.DIV_NEW == 0) begin
el2_exu_div_existing_1bit_cheapshortq i_existing_1bit_div_cheapshortq (
.clk (clk), // I
.rst_l (rst_l), // I
@ -55,12 +53,12 @@ import el2_pkg::*;
.dividend_in(dividend[31:0]), // I
.divisor_in (divisor[31:0]), // I
.valid_out (finish_dly), // O
.data_out ( out_raw[31:0] )); // O
.data_out (out_raw[31:0])
); // O
end
if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 1) )
begin
if ((pt.DIV_NEW == 1) & (pt.DIV_BIT == 1)) begin
el2_exu_div_new_1bit_fullshortq i_new_1bit_div_fullshortq (
.clk (clk), // I
.rst_l (rst_l), // I
@ -72,12 +70,12 @@ import el2_pkg::*;
.dividend_in(dividend[31:0]), // I
.divisor_in (divisor[31:0]), // I
.valid_out (finish_dly), // O
.data_out ( out_raw[31:0] )); // O
.data_out (out_raw[31:0])
); // O
end
if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 2) )
begin
if ((pt.DIV_NEW == 1) & (pt.DIV_BIT == 2)) begin
el2_exu_div_new_2bit_fullshortq i_new_2bit_div_fullshortq (
.clk (clk), // I
.rst_l (rst_l), // I
@ -89,12 +87,12 @@ import el2_pkg::*;
.dividend_in(dividend[31:0]), // I
.divisor_in (divisor[31:0]), // I
.valid_out (finish_dly), // O
.data_out ( out_raw[31:0] )); // O
.data_out (out_raw[31:0])
); // O
end
if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 3) )
begin
if ((pt.DIV_NEW == 1) & (pt.DIV_BIT == 3)) begin
el2_exu_div_new_3bit_fullshortq i_new_3bit_div_fullshortq (
.clk (clk), // I
.rst_l (rst_l), // I
@ -106,12 +104,12 @@ import el2_pkg::*;
.dividend_in(dividend[31:0]), // I
.divisor_in (divisor[31:0]), // I
.valid_out (finish_dly), // O
.data_out ( out_raw[31:0] )); // O
.data_out (out_raw[31:0])
); // O
end
if ( (pt.DIV_NEW == 1) & (pt.DIV_BIT == 4) )
begin
if ((pt.DIV_NEW == 1) & (pt.DIV_BIT == 4)) begin
el2_exu_div_new_4bit_fullshortq i_new_4bit_div_fullshortq (
.clk (clk), // I
.rst_l (rst_l), // I
@ -123,7 +121,8 @@ import el2_pkg::*;
.dividend_in(dividend[31:0]), // I
.divisor_in (divisor[31:0]), // I
.valid_out (finish_dly), // O
.data_out ( out_raw[31:0] )); // O
.data_out (out_raw[31:0])
); // O
end
@ -136,8 +135,7 @@ endmodule // el2_exu_div_ctl
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
module el2_exu_div_existing_1bit_cheapshortq
(
module el2_exu_div_existing_1bit_cheapshortq (
input logic clk, // Top level clock
input logic rst_l, // Reset
input logic scan_mode, // Scan mode
@ -199,7 +197,12 @@ module el2_exu_div_existing_1bit_cheapshortq
rvdffe #(23) i_misc_ff (.*, .clk(clk), .en(div_clken), .din ({valid_in & ~cancel,
rvdffe #(23) i_misc_ff (
.*,
.clk(clk),
.en(div_clken),
.din({
valid_in & ~cancel,
finish & ~cancel,
run_in,
count_in[5:0],
@ -210,9 +213,11 @@ module el2_exu_div_existing_1bit_cheapshortq
smallnum_case,
smallnum[3:0],
shortq_enable,
shortq_shift[3:0]}),
shortq_shift[3:0]
}),
.dout({valid_ff_x,
.dout({
valid_ff_x,
finish_ff,
run_state,
count[5:0],
@ -223,16 +228,45 @@ module el2_exu_div_existing_1bit_cheapshortq
smallnum_case_ff,
smallnum_ff[3:0],
shortq_enable_ff,
shortq_shift_xx[3:0]}));
shortq_shift_xx[3:0]
})
);
rvdffe #(33) mff (.*, .clk(clk), .en(valid_in), .din({signed_in & divisor_in[31], divisor_in[31:0]}), .dout(m_ff[32:0]));
rvdffe #(33) qff (.*, .clk(clk), .en(qff_enable), .din(q_in[32:0]), .dout(q_ff[32:0]));
rvdffe #(33) aff (.*, .clk(clk), .en(aff_enable), .din(a_in[32:0]), .dout(a_ff[32:0]));
rvdffe #(33) mff (
.*,
.clk (clk),
.en (valid_in),
.din ({signed_in & divisor_in[31], divisor_in[31:0]}),
.dout(m_ff[32:0])
);
rvdffe #(33) qff (
.*,
.clk (clk),
.en (qff_enable),
.din (q_in[32:0]),
.dout(q_ff[32:0])
);
rvdffe #(33) aff (
.*,
.clk (clk),
.en (aff_enable),
.din (a_in[32:0]),
.dout(a_ff[32:0])
);
rvtwoscomp #(32) i_dividend_comp (.din(q_ff[31:0]), .dout(dividend_comp[31:0]));
rvtwoscomp #(32) i_q_ff_comp (.din(q_ff[31:0]), .dout(q_ff_comp[31:0]));
rvtwoscomp #(32) i_a_ff_comp (.din(a_ff[31:0]), .dout(a_ff_comp[31:0]));
rvtwoscomp #(32) i_dividend_comp (
.din (q_ff[31:0]),
.dout(dividend_comp[31:0])
);
rvtwoscomp #(32) i_q_ff_comp (
.din (q_ff[31:0]),
.dout(q_ff_comp[31:0])
);
rvtwoscomp #(32) i_a_ff_comp (
.din (a_ff[31:0]),
.dout(a_ff_comp[31:0])
);
assign valid_x = valid_ff_x & ~cancel;
@ -444,8 +478,7 @@ endmodule // el2_exu_div_existing_1bit_cheapshortq
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
module el2_exu_div_new_1bit_fullshortq
(
module el2_exu_div_new_1bit_fullshortq (
input logic clk, // Top level clock
input logic rst_l, // Reset
input logic scan_mode, // Scan mode
@ -504,13 +537,58 @@ module el2_exu_div_new_1bit_fullshortq
rvdffe #(19) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:0], finish, count_in[6:0]}),
.dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:0], finish_ff, count_ff[6:0]}));
rvdffe #(19) i_misc_ff (
.*,
.clk(clk),
.en(misc_enable),
.din({
valid_ff_in,
control_in[2:0],
by_zero_case,
shortq_enable,
shortq_shift[4:0],
finish,
count_in[6:0]
}),
.dout({
valid_ff,
control_ff[2:0],
by_zero_case_ff,
shortq_enable_ff,
shortq_shift_ff[4:0],
finish_ff,
count_ff[6:0]
})
);
rvdffe #(32) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[31:0]), .dout(a_ff[31:0]));
rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0]));
rvdffe #(32) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[31:0]), .dout(r_ff[31:0]));
rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0]));
rvdffe #(32) i_a_ff (
.*,
.clk (clk),
.en (a_enable),
.din (a_in[31:0]),
.dout(a_ff[31:0])
);
rvdffe #(33) i_b_ff (
.*,
.clk (clk),
.en (b_enable),
.din (b_in[32:0]),
.dout(b_ff[32:0])
);
rvdffe #(32) i_r_ff (
.*,
.clk (clk),
.en (rq_enable),
.din (r_in[31:0]),
.dout(r_ff[31:0])
);
rvdffe #(32) i_q_ff (
.*,
.clk (clk),
.en (rq_enable),
.din (q_in[31:0]),
.dout(q_ff[31:0])
);
@ -530,9 +608,7 @@ module el2_exu_div_new_1bit_fullshortq
assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff;
assign running_state = (|count_ff[6:0]) | shortq_enable_ff;
assign finish_raw = smallnum_case |
by_zero_case |
(count_ff[6:0] == 7'd32);
assign finish_raw = smallnum_case | by_zero_case | (count_ff[6:0] == 7'd32);
assign finish = finish_raw & ~cancel;
@ -590,7 +666,10 @@ module el2_exu_div_new_1bit_fullshortq
assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) |
( {32{twos_comp_b_sel}} & b_ff[31:0] );
rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0]));
rvtwoscomp #(32) i_twos_comp (
.din (twos_comp_in[31:0]),
.dout(twos_comp_out[31:0])
);
@ -669,11 +748,13 @@ module el2_exu_div_new_1bit_fullshortq
el2_exu_div_cls i_a_cls (
.operand(shortq_dividend[32:0]),
.cls ( dw_a_enc[4:0] ));
.cls (dw_a_enc[4:0])
);
el2_exu_div_cls i_b_cls (
.operand(b_ff[32:0]),
.cls ( dw_b_enc[4:0] ));
.cls (dw_b_enc[4:0])
);
assign dw_a_enc[5] = 1'b0;
assign dw_b_enc[5] = 1'b0;
@ -702,8 +783,7 @@ endmodule // el2_exu_div_new_1bit_fullshortq
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
module el2_exu_div_new_2bit_fullshortq
(
module el2_exu_div_new_2bit_fullshortq (
input logic clk, // Top level clock
input logic rst_l, // Reset
input logic scan_mode, // Scan mode
@ -766,13 +846,58 @@ module el2_exu_div_new_2bit_fullshortq
rvdffe #(18) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:1], finish, count_in[6:0]}),
.dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:1], finish_ff, count_ff[6:0]}));
rvdffe #(18) i_misc_ff (
.*,
.clk(clk),
.en(misc_enable),
.din({
valid_ff_in,
control_in[2:0],
by_zero_case,
shortq_enable,
shortq_shift[4:1],
finish,
count_in[6:0]
}),
.dout({
valid_ff,
control_ff[2:0],
by_zero_case_ff,
shortq_enable_ff,
shortq_shift_ff[4:1],
finish_ff,
count_ff[6:0]
})
);
rvdffe #(32) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[31:0]), .dout(a_ff[31:0]));
rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0]));
rvdffe #(32) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[31:0]), .dout(r_ff[31:0]));
rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0]));
rvdffe #(32) i_a_ff (
.*,
.clk (clk),
.en (a_enable),
.din (a_in[31:0]),
.dout(a_ff[31:0])
);
rvdffe #(33) i_b_ff (
.*,
.clk (clk),
.en (b_enable),
.din (b_in[32:0]),
.dout(b_ff[32:0])
);
rvdffe #(32) i_r_ff (
.*,
.clk (clk),
.en (rq_enable),
.din (r_in[31:0]),
.dout(r_ff[31:0])
);
rvdffe #(32) i_q_ff (
.*,
.clk (clk),
.en (rq_enable),
.din (q_in[31:0]),
.dout(q_ff[31:0])
);
@ -792,9 +917,7 @@ module el2_exu_div_new_2bit_fullshortq
assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff;
assign running_state = (|count_ff[6:0]) | shortq_enable_ff;
assign finish_raw = smallnum_case |
by_zero_case |
(count_ff[6:0] == 7'd32);
assign finish_raw = smallnum_case | by_zero_case | (count_ff[6:0] == 7'd32);
assign finish = finish_raw & ~cancel;
@ -864,7 +987,10 @@ module el2_exu_div_new_2bit_fullshortq
assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) |
( {32{twos_comp_b_sel}} & b_ff[31:0] );
rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0]));
rvtwoscomp #(32) i_twos_comp (
.din (twos_comp_in[31:0]),
.dout(twos_comp_out[31:0])
);
@ -943,11 +1069,13 @@ module el2_exu_div_new_2bit_fullshortq
el2_exu_div_cls i_a_cls (
.operand(shortq_dividend[32:0]),
.cls ( dw_a_enc[4:0] ));
.cls (dw_a_enc[4:0])
);
el2_exu_div_cls i_b_cls (
.operand(b_ff[32:0]),
.cls ( dw_b_enc[4:0] ));
.cls (dw_b_enc[4:0])
);
assign dw_a_enc[5] = 1'b0;
assign dw_b_enc[5] = 1'b0;
@ -976,8 +1104,7 @@ endmodule // el2_exu_div_new_2bit_fullshortq
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
module el2_exu_div_new_3bit_fullshortq
(
module el2_exu_div_new_3bit_fullshortq (
input logic clk, // Top level clock
input logic rst_l, // Reset
input logic scan_mode, // Scan mode
@ -1018,7 +1145,14 @@ module el2_exu_div_new_3bit_fullshortq
logic rq_enable;
logic r_sign_sel;
logic r_restore_sel;
logic r_adder1_sel, r_adder2_sel, r_adder3_sel, r_adder4_sel, r_adder5_sel, r_adder6_sel, r_adder7_sel;
logic
r_adder1_sel,
r_adder2_sel,
r_adder3_sel,
r_adder4_sel,
r_adder5_sel,
r_adder6_sel,
r_adder7_sel;
logic [32:0] r_in, r_ff;
logic twos_comp_q_sel, twos_comp_b_sel;
@ -1048,13 +1182,58 @@ module el2_exu_div_new_3bit_fullshortq
rvdffe #(19) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:0], finish, count_in[6:0]}),
.dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:0], finish_ff, count_ff[6:0]}));
rvdffe #(19) i_misc_ff (
.*,
.clk(clk),
.en(misc_enable),
.din({
valid_ff_in,
control_in[2:0],
by_zero_case,
shortq_enable,
shortq_shift[4:0],
finish,
count_in[6:0]
}),
.dout({
valid_ff,
control_ff[2:0],
by_zero_case_ff,
shortq_enable_ff,
shortq_shift_ff[4:0],
finish_ff,
count_ff[6:0]
})
);
rvdffe #(33) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[32:0]), .dout(a_ff[32:0]));
rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0]));
rvdffe #(33) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[32:0]), .dout(r_ff[32:0]));
rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0]));
rvdffe #(33) i_a_ff (
.*,
.clk (clk),
.en (a_enable),
.din (a_in[32:0]),
.dout(a_ff[32:0])
);
rvdffe #(33) i_b_ff (
.*,
.clk (clk),
.en (b_enable),
.din (b_in[32:0]),
.dout(b_ff[32:0])
);
rvdffe #(33) i_r_ff (
.*,
.clk (clk),
.en (rq_enable),
.din (r_in[32:0]),
.dout(r_ff[32:0])
);
rvdffe #(32) i_q_ff (
.*,
.clk (clk),
.en (rq_enable),
.din (q_in[31:0]),
.dout(q_ff[31:0])
);
@ -1074,9 +1253,7 @@ module el2_exu_div_new_3bit_fullshortq
assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff;
assign running_state = (|count_ff[6:0]) | shortq_enable_ff;
assign finish_raw = smallnum_case |
by_zero_case |
(count_ff[6:0] == 7'd33);
assign finish_raw = smallnum_case | by_zero_case | (count_ff[6:0] == 7'd33);
assign finish = finish_raw & ~cancel;
@ -1162,7 +1339,10 @@ module el2_exu_div_new_3bit_fullshortq
assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) |
( {32{twos_comp_b_sel}} & b_ff[31:0] );
rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0]));
rvtwoscomp #(32) i_twos_comp (
.din (twos_comp_in[31:0]),
.dout(twos_comp_out[31:0])
);
@ -1241,11 +1421,13 @@ module el2_exu_div_new_3bit_fullshortq
el2_exu_div_cls i_a_cls (
.operand(shortq_dividend[32:0]),
.cls ( dw_a_enc[4:0] ));
.cls (dw_a_enc[4:0])
);
el2_exu_div_cls i_b_cls (
.operand(b_ff[32:0]),
.cls ( dw_b_enc[4:0] ));
.cls (dw_b_enc[4:0])
);
assign dw_a_enc[5] = 1'b0;
assign dw_b_enc[5] = 1'b0;
@ -1308,8 +1490,7 @@ endmodule // el2_exu_div_new_3bit_fullshortq
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
module el2_exu_div_new_4bit_fullshortq
(
module el2_exu_div_new_4bit_fullshortq (
input logic clk, // Top level clock
input logic rst_l, // Reset
input logic scan_mode, // Scan mode
@ -1391,13 +1572,58 @@ module el2_exu_div_new_4bit_fullshortq
rvdffe #(19) i_misc_ff (.*, .clk(clk), .en(misc_enable), .din ({valid_ff_in, control_in[2:0], by_zero_case, shortq_enable, shortq_shift[4:0], finish, count_in[6:0]}),
.dout({valid_ff, control_ff[2:0], by_zero_case_ff, shortq_enable_ff, shortq_shift_ff[4:0], finish_ff, count_ff[6:0]}));
rvdffe #(19) i_misc_ff (
.*,
.clk(clk),
.en(misc_enable),
.din({
valid_ff_in,
control_in[2:0],
by_zero_case,
shortq_enable,
shortq_shift[4:0],
finish,
count_in[6:0]
}),
.dout({
valid_ff,
control_ff[2:0],
by_zero_case_ff,
shortq_enable_ff,
shortq_shift_ff[4:0],
finish_ff,
count_ff[6:0]
})
);
rvdffe #(32) i_a_ff (.*, .clk(clk), .en(a_enable), .din(a_in[31:0]), .dout(a_ff[31:0]));
rvdffe #(33) i_b_ff (.*, .clk(clk), .en(b_enable), .din(b_in[32:0]), .dout(b_ff[32:0]));
rvdffe #(33) i_r_ff (.*, .clk(clk), .en(rq_enable), .din(r_in[32:0]), .dout(r_ff[32:0]));
rvdffe #(32) i_q_ff (.*, .clk(clk), .en(rq_enable), .din(q_in[31:0]), .dout(q_ff[31:0]));
rvdffe #(32) i_a_ff (
.*,
.clk (clk),
.en (a_enable),
.din (a_in[31:0]),
.dout(a_ff[31:0])
);
rvdffe #(33) i_b_ff (
.*,
.clk (clk),
.en (b_enable),
.din (b_in[32:0]),
.dout(b_ff[32:0])
);
rvdffe #(33) i_r_ff (
.*,
.clk (clk),
.en (rq_enable),
.din (r_in[32:0]),
.dout(r_ff[32:0])
);
rvdffe #(32) i_q_ff (
.*,
.clk (clk),
.en (rq_enable),
.din (q_in[31:0]),
.dout(q_ff[31:0])
);
@ -1417,9 +1643,7 @@ module el2_exu_div_new_4bit_fullshortq
assign misc_enable = valid_in | valid_ff | cancel | running_state | finish_ff;
assign running_state = (|count_ff[6:0]) | shortq_enable_ff;
assign finish_raw = smallnum_case |
by_zero_case |
(count_ff[6:0] == 7'd32);
assign finish_raw = smallnum_case | by_zero_case | (count_ff[6:0] == 7'd32);
assign finish = finish_raw & ~cancel;
@ -1569,7 +1793,10 @@ module el2_exu_div_new_4bit_fullshortq
assign twos_comp_in[31:0] = ( {32{twos_comp_q_sel}} & q_ff[31:0] ) |
( {32{twos_comp_b_sel}} & b_ff[31:0] );
rvtwoscomp #(32) i_twos_comp (.din(twos_comp_in[31:0]), .dout(twos_comp_out[31:0]));
rvtwoscomp #(32) i_twos_comp (
.din (twos_comp_in[31:0]),
.dout(twos_comp_out[31:0])
);
@ -1648,11 +1875,13 @@ module el2_exu_div_new_4bit_fullshortq
el2_exu_div_cls i_a_cls (
.operand(shortq_dividend[32:0]),
.cls ( dw_a_enc[4:0] ));
.cls (dw_a_enc[4:0])
);
el2_exu_div_cls i_b_cls (
.operand(b_ff[32:0]),
.cls ( dw_b_enc[4:0] ));
.cls (dw_b_enc[4:0])
);
assign dw_a_enc[5] = 1'b0;
assign dw_b_enc[5] = 1'b0;
@ -1715,8 +1944,7 @@ endmodule // el2_exu_div_new_4bit_fullshortq
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
module el2_exu_div_cls
(
module el2_exu_div_cls (
input logic [32:0] operand,
output logic [4:0] cls // Count leading sign bits - "n" format ignoring [32]

View File

@ -18,8 +18,7 @@ module el2_exu_mul_ctl
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk, // Top level clock
input logic rst_l, // Reset
input logic scan_mode, // Scan mode
@ -82,32 +81,25 @@ import el2_pkg::*;
logic ap_bfp;
if (pt.BITMANIP_ZBE == 1)
begin
if (pt.BITMANIP_ZBE == 1) begin
assign ap_bcompress = mul_p.bcompress;
assign ap_bdecompress = mul_p.bdecompress;
end
else
begin
end else begin
assign ap_bcompress = 1'b0;
assign ap_bdecompress = 1'b0;
end
if (pt.BITMANIP_ZBC == 1)
begin
if (pt.BITMANIP_ZBC == 1) begin
assign ap_clmul = mul_p.clmul;
assign ap_clmulh = mul_p.clmulh;
assign ap_clmulr = mul_p.clmulr;
end
else
begin
end else begin
assign ap_clmul = 1'b0;
assign ap_clmulh = 1'b0;
assign ap_clmulr = 1'b0;
end
if (pt.BITMANIP_ZBP == 1)
begin
if (pt.BITMANIP_ZBP == 1) begin
assign ap_grev = mul_p.grev;
assign ap_gorc = mul_p.gorc;
assign ap_shfl = mul_p.shfl;
@ -115,9 +107,7 @@ import el2_pkg::*;
assign ap_xperm_n = mul_p.xperm_n;
assign ap_xperm_b = mul_p.xperm_b;
assign ap_xperm_h = mul_p.xperm_h;
end
else
begin
end else begin
assign ap_grev = 1'b0;
assign ap_gorc = 1'b0;
assign ap_shfl = 1'b0;
@ -127,17 +117,14 @@ import el2_pkg::*;
assign ap_xperm_h = 1'b0;
end
if (pt.BITMANIP_ZBR == 1)
begin
if (pt.BITMANIP_ZBR == 1) begin
assign ap_crc32_b = mul_p.crc32_b;
assign ap_crc32_h = mul_p.crc32_h;
assign ap_crc32_w = mul_p.crc32_w;
assign ap_crc32c_b = mul_p.crc32c_b;
assign ap_crc32c_h = mul_p.crc32c_h;
assign ap_crc32c_w = mul_p.crc32c_w;
end
else
begin
end else begin
assign ap_crc32_b = 1'b0;
assign ap_crc32_h = 1'b0;
assign ap_crc32_w = 1'b0;
@ -146,12 +133,9 @@ import el2_pkg::*;
assign ap_crc32c_w = 1'b0;
end
if (pt.BITMANIP_ZBF == 1)
begin
if (pt.BITMANIP_ZBF == 1) begin
assign ap_bfp = mul_p.bfp;
end
else
begin
end else begin
assign ap_bfp = 1'b0;
end
@ -177,8 +161,20 @@ import el2_pkg::*;
logic signed [32:0] rs1_x;
logic signed [32:0] rs2_x;
rvdffe #(34) i_a_x_ff (.*, .clk(clk), .din({mul_p.low,rs1_ext_in[32:0]}), .dout({low_x,rs1_x[32:0]}), .en(mul_x_enable));
rvdffe #(33) i_b_x_ff (.*, .clk(clk), .din( rs2_ext_in[32:0] ), .dout( rs2_x[32:0] ), .en(mul_x_enable));
rvdffe #(34) i_a_x_ff (
.*,
.clk (clk),
.din ({mul_p.low, rs1_ext_in[32:0]}),
.dout({low_x, rs1_x[32:0]}),
.en (mul_x_enable)
);
rvdffe #(33) i_b_x_ff (
.*,
.clk (clk),
.din (rs2_ext_in[32:0]),
.dout(rs2_x[32:0]),
.en (mul_x_enable)
);
assign prod_x[65:0] = rs1_x * rs2_x;
@ -196,18 +192,15 @@ import el2_pkg::*;
integer bcompress_i, bcompress_j;
always_comb
begin
always_comb begin
bcompress_j = 0;
bcompress_test_bit_d = 1'b0;
bcompress_d[31:0] = 32'b0;
for (bcompress_i=0; bcompress_i<32; bcompress_i++)
begin
for (bcompress_i = 0; bcompress_i < 32; bcompress_i++) begin
bcompress_test_bit_d = rs2_in[bcompress_i];
if (bcompress_test_bit_d)
begin
if (bcompress_test_bit_d) begin
bcompress_d[bcompress_j] = rs1_in[bcompress_i];
bcompress_j = bcompress_j + 1;
end // IF bcompress_test_bit
@ -223,18 +216,15 @@ import el2_pkg::*;
integer bdecompress_i, bdecompress_j;
always_comb
begin
always_comb begin
bdecompress_j = 0;
bdecompress_test_bit_d = 1'b0;
bdecompress_d[31:0] = 32'b0;
for (bdecompress_i=0; bdecompress_i<32; bdecompress_i++)
begin
for (bdecompress_i = 0; bdecompress_i < 32; bdecompress_i++) begin
bdecompress_test_bit_d = rs2_in[bdecompress_i];
if (bdecompress_test_bit_d)
begin
if (bdecompress_test_bit_d) begin
bdecompress_d[bdecompress_i] = rs1_in[bdecompress_j];
bdecompress_j = bdecompress_j + 1;
end // IF bdecompress_test_bit
@ -584,34 +574,28 @@ import el2_pkg::*;
assign crc32c_poly_rev[31:0] = 32'h82F63B78; // bit reverse of 32'h1EDC6F41
always_comb
begin
always_comb begin
crc32_bd[31:0] = rs1_in[31:0];
for (crc32_bi=0; crc32_bi<8; crc32_bi++)
begin
for (crc32_bi = 0; crc32_bi < 8; crc32_bi++) begin
crc32_bd[31:0] = (crc32_bd[31:0] >> 1) ^ (crc32_poly_rev[31:0] & {32{crc32_bd[0]}});
end // FOR crc32_bi
end // ALWAYS_COMB
always_comb
begin
always_comb begin
crc32_hd[31:0] = rs1_in[31:0];
for (crc32_hi=0; crc32_hi<16; crc32_hi++)
begin
for (crc32_hi = 0; crc32_hi < 16; crc32_hi++) begin
crc32_hd[31:0] = (crc32_hd[31:0] >> 1) ^ (crc32_poly_rev[31:0] & {32{crc32_hd[0]}});
end // FOR crc32_hi
end // ALWAYS_COMB
always_comb
begin
always_comb begin
crc32_wd[31:0] = rs1_in[31:0];
for (crc32_wi=0; crc32_wi<32; crc32_wi++)
begin
for (crc32_wi = 0; crc32_wi < 32; crc32_wi++) begin
crc32_wd[31:0] = (crc32_wd[31:0] >> 1) ^ (crc32_poly_rev[31:0] & {32{crc32_wd[0]}});
end // FOR crc32_wi
end // ALWAYS_COMB
@ -619,34 +603,28 @@ import el2_pkg::*;
always_comb
begin
always_comb begin
crc32c_bd[31:0] = rs1_in[31:0];
for (crc32c_bi=0; crc32c_bi<8; crc32c_bi++)
begin
for (crc32c_bi = 0; crc32c_bi < 8; crc32c_bi++) begin
crc32c_bd[31:0] = (crc32c_bd[31:0] >> 1) ^ (crc32c_poly_rev[31:0] & {32{crc32c_bd[0]}});
end // FOR crc32c_bi
end // ALWAYS_COMB
always_comb
begin
always_comb begin
crc32c_hd[31:0] = rs1_in[31:0];
for (crc32c_hi=0; crc32c_hi<16; crc32c_hi++)
begin
for (crc32c_hi = 0; crc32c_hi < 16; crc32c_hi++) begin
crc32c_hd[31:0] = (crc32c_hd[31:0] >> 1) ^ (crc32c_poly_rev[31:0] & {32{crc32c_hd[0]}});
end // FOR crc32c_hi
end // ALWAYS_COMB
always_comb
begin
always_comb begin
crc32c_wd[31:0] = rs1_in[31:0];
for (crc32c_wi=0; crc32c_wi<32; crc32c_wi++)
begin
for (crc32c_wi = 0; crc32c_wi < 32; crc32c_wi++) begin
crc32c_wd[31:0] = (crc32c_wd[31:0] >> 1) ^ (crc32c_poly_rev[31:0] & {32{crc32c_wd[0]}});
end // FOR crc32c_wi
end // ALWAYS_COMB
@ -723,7 +701,13 @@ import el2_pkg::*;
rvdffe #(33) i_bitmanip_ff (.*, .clk(clk), .din({bitmanip_sel_d,bitmanip_d[31:0]}), .dout({bitmanip_sel_x,bitmanip_x[31:0]}), .en(bit_x_enable));
rvdffe #(33) i_bitmanip_ff (
.*,
.clk (clk),
.din ({bitmanip_sel_d, bitmanip_d[31:0]}),
.dout({bitmanip_sel_x, bitmanip_x[31:0]}),
.en (bit_x_enable)
);

View File

@ -23,8 +23,7 @@ module el2_ifu
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in.
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
@ -242,14 +241,12 @@ import el2_pkg::*;
// fetch control
el2_ifu_ifc_ctl #(.pt(pt)) ifc (.*
);
el2_ifu_ifc_ctl #(.pt(pt)) ifc (.*);
// branch predictor
if (pt.BTB_ENABLE == 1) begin : bpred
el2_ifu_bp_ctl #(.pt(pt)) bp (.*);
end
else begin : bpred
end else begin : bpred
assign ifu_bp_hit_taken_f = '0;
// verif wires
logic btb_wr_en_way0, btb_wr_en_way1, dec_tlu_error_wb;
@ -284,14 +281,14 @@ import el2_pkg::*;
// aligner
el2_ifu_aln_ctl #(.pt(pt)) aln (
.*
);
el2_ifu_aln_ctl #(.pt(pt)) aln (.*);
// icache
el2_ifu_mem_ctl #(.pt(pt)) mem_ctl
(.*,
el2_ifu_mem_ctl #(
.pt(pt)
) mem_ctl (
.*,
.ic_data_f(ic_data_f[31:0])
);
@ -328,12 +325,20 @@ import el2_pkg::*;
logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] btb_rd_addr_f;
`define DEC top.rvtop.swerv.dec
`define EXU top.rvtop.swerv.exu
el2_btb_addr_hash f2hash(.pc(ifc_fetch_addr_f[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]), .hash(btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
el2_btb_addr_hash f2hash (
.pc (ifc_fetch_addr_f[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
.hash(btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO])
);
logic [31:0] mppc_ns, mppc;
logic exu_flush_final_d1;
assign mppc_ns[31:1] = `EXU.i0_flush_upper_x ? `EXU.exu_i0_pc_x : `EXU.dec_i0_pc_d;
assign mppc_ns[0] = 1'b0;
rvdff #(33) junk_ff (.*, .clk(active_clk), .din({mppc_ns[31:0], exu_flush_final}), .dout({mppc[31:0], exu_flush_final_d1}));
rvdff #(33) junk_ff (
.*,
.clk (active_clk),
.din ({mppc_ns[31:0], exu_flush_final}),
.dout({mppc[31:0], exu_flush_final_d1})
);
logic tmp_bnk;
assign tmp_bnk = bpred.bp.btb_sel_f[1];
@ -348,17 +353,71 @@ import el2_pkg::*;
$display("RS_CONFIG: %d", pt.RET_STACK_SIZE);
end
if(exu_flush_final_d1 & ~(dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error) & (exu_mp_pkt.misp | exu_mp_pkt.ataken))
$display("%7d BTB_MP : index: %0h bank: %0h call: %b ret: %b ataken: %b hist: %h valid: %b tag: %h targ: %h eghr: %b pred: %b ghr_index: %h brpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha, exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO], 1'b0, exu_mp_call, exu_mp_ret, exu_mp_ataken, exu_mp_hist[1:0], exu_mp_valid, exu_mp_btag[pt.BTB_BTAG_SIZE-1:0], {exu_flush_path_final[31:1], 1'b0}, exu_mp_eghr[pt.BHT_GHR_SIZE-1:0], exu_mp_valid, bpred.bp.bht_wr_addr0, mppc[31:0], exu_mp_pkt.way);
$display(
"%7d BTB_MP : index: %0h bank: %0h call: %b ret: %b ataken: %b hist: %h valid: %b tag: %h targ: %h eghr: %b pred: %b ghr_index: %h brpc: %h way: %h",
`DEC.tlu.mcyclel[31:0] + 32'ha,
exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],
1'b0,
exu_mp_call,
exu_mp_ret,
exu_mp_ataken,
exu_mp_hist[1:0],
exu_mp_valid,
exu_mp_btag[pt.BTB_BTAG_SIZE-1:0],
{
exu_flush_path_final[31:1], 1'b0
},
exu_mp_eghr[pt.BHT_GHR_SIZE-1:0],
exu_mp_valid,
bpred.bp.bht_wr_addr0,
mppc[31:0],
exu_mp_pkt.way
);
for (int i = 0; i < 8; i++) begin
if (ifu_bp_valid_f[i] & ifc_fetch_req_f)
$display("%7d BTB_HIT : index: %0h bank: %0h call: %b ret: %b taken: %b strength: %b tag: %h targ: %0h ghr: %4b ghr_index: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],bpred.bp.btb_sel_f[1], bpred.bp.btb_rd_call_f, bpred.bp.btb_rd_ret_f, ifu_bp_hist1_f[tmp_bnk], ifu_bp_hist0_f[tmp_bnk], bpred.bp.fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0], {ifu_bp_btb_target_f[31:1], 1'b0}, bpred.bp.fghr[pt.BHT_GHR_SIZE-1:0], bpred.bp.bht_rd_addr_f, ifu_bp_way_f[tmp_bnk]);
$display(
"%7d BTB_HIT : index: %0h bank: %0h call: %b ret: %b taken: %b strength: %b tag: %h targ: %0h ghr: %4b ghr_index: %h way: %h",
`DEC.tlu.mcyclel[31:0] + 32'ha,
btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],
bpred.bp.btb_sel_f[1],
bpred.bp.btb_rd_call_f,
bpred.bp.btb_rd_ret_f,
ifu_bp_hist1_f[tmp_bnk],
ifu_bp_hist0_f[tmp_bnk],
bpred.bp.fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0],
{
ifu_bp_btb_target_f[31:1], 1'b0
},
bpred.bp.fghr[pt.BHT_GHR_SIZE-1:0],
bpred.bp.bht_rd_addr_f,
ifu_bp_way_f[tmp_bnk]
);
end
if (dec_tlu_br0_r_pkt.valid & ~(dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error))
$display("%7d BTB_UPD0: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bpred.bp.br0_hashed_wb[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO],{dec_tlu_br0_r_pkt.middle}, dec_tlu_br0_r_pkt.hist, dec_tlu_br0_r_pkt.way);
$display(
"%7d BTB_UPD0: ghr_index: %0h bank: %0h hist: %h way: %h",
`DEC.tlu.mcyclel[31:0] + 32'ha,
bpred.bp.br0_hashed_wb[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO],
{
dec_tlu_br0_r_pkt.middle
},
dec_tlu_br0_r_pkt.hist,
dec_tlu_br0_r_pkt.way
);
if (dec_tlu_br0_r_pkt.br_error | dec_tlu_br0_r_pkt.br_start_error)
$display("%7d BTB_ERR0: index: %0h bank: %0h start: %b rfpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,exu_i0_br_index_r[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],1'b0, dec_tlu_br0_r_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br0_r_pkt.way);
$display(
"%7d BTB_ERR0: index: %0h bank: %0h start: %b rfpc: %h way: %h",
`DEC.tlu.mcyclel[31:0] + 32'ha,
exu_i0_br_index_r[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO],
1'b0,
dec_tlu_br0_r_pkt.br_start_error,
{
exu_flush_path_final[31:1], 1'b0
},
dec_tlu_br0_r_pkt.way
);
end // always @ (negedge clk)
function [1:0] encode4_2;
input [3:0] in;

View File

@ -22,8 +22,7 @@ module el2_ifu_aln_ctl
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic scan_mode, // Flop scan mode control
input logic rst_l, // reset, active low
@ -65,7 +64,9 @@ import el2_pkg::*;
input logic [pt.BHT_GHR_SIZE-1:0] ifu_bp_fghr_f, // fetch GHR
input logic [31:1] ifu_bp_btb_target_f, // predicted RET target
input logic [11:0] ifu_bp_poffset_f, // predicted target offset
input logic [1:0] [$clog2(pt.BTB_SIZE)-1:0] ifu_bp_fa_index_f, // predicted branch index (fully associative option)
input logic [1:0][$clog2(
pt.BTB_SIZE
)-1:0] ifu_bp_fa_index_f, // predicted branch index (fully associative option)
input logic [1:0] ifu_bp_hist0_f, // history counters for all 4 potential branches, bit 1, right justified
input logic [1:0] ifu_bp_hist1_f, // history counters for all 4 potential branches, bit 1, right justified
@ -204,57 +205,143 @@ import el2_pkg::*;
assign error_stall_in = (error_stall | ifu_async_error_start) & ~exu_flush_final;
rvdff #(.WIDTH(7)) bundle1ff (.*,
rvdff #(
.WIDTH(7)
) bundle1ff (
.*,
.clk (active_clk),
.din ({wrptr_in[1:0], rdptr_in[1:0], q2off_in, q1off_in, q0off_in}),
.dout({wrptr[1:0], rdptr[1:0], q2off, q1off, q0off})
);
rvdffie #(.WIDTH(7),.OVERRIDE(1)) bundle2ff (.*,
rvdffie #(
.WIDTH(7),
.OVERRIDE(1)
) bundle2ff (
.*,
.din ({error_stall_in, f2val_in[1:0], f1val_in[1:0], f0val_in[1:0]}),
.dout({error_stall, f2val[1:0], f1val[1:0], f0val[1:0]})
);
if (pt.BTB_ENABLE == 1) begin
rvdffe #(BRDATA_SIZE) brdata2ff (.*, .clk(clk), .en(qwen[2]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata2[BRDATA_SIZE-1:0]));
rvdffe #(BRDATA_SIZE) brdata1ff (.*, .clk(clk), .en(qwen[1]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata1[BRDATA_SIZE-1:0]));
rvdffe #(BRDATA_SIZE) brdata0ff (.*, .clk(clk), .en(qwen[0]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata0[BRDATA_SIZE-1:0]));
rvdffe #(MSIZE) misc2ff (.*, .clk(clk), .en(qwen[2]), .din(misc_data_in[MHI:0]), .dout(misc2[MHI:0]));
rvdffe #(MSIZE) misc1ff (.*, .clk(clk), .en(qwen[1]), .din(misc_data_in[MHI:0]), .dout(misc1[MHI:0]));
rvdffe #(MSIZE) misc0ff (.*, .clk(clk), .en(qwen[0]), .din(misc_data_in[MHI:0]), .dout(misc0[MHI:0]));
end
else begin
rvdffe #(BRDATA_SIZE) brdata2ff (
.*,
.clk (clk),
.en (qwen[2]),
.din (brdata_in[BRDATA_SIZE-1:0]),
.dout(brdata2[BRDATA_SIZE-1:0])
);
rvdffe #(BRDATA_SIZE) brdata1ff (
.*,
.clk (clk),
.en (qwen[1]),
.din (brdata_in[BRDATA_SIZE-1:0]),
.dout(brdata1[BRDATA_SIZE-1:0])
);
rvdffe #(BRDATA_SIZE) brdata0ff (
.*,
.clk (clk),
.en (qwen[0]),
.din (brdata_in[BRDATA_SIZE-1:0]),
.dout(brdata0[BRDATA_SIZE-1:0])
);
rvdffe #(MSIZE) misc2ff (
.*,
.clk (clk),
.en (qwen[2]),
.din (misc_data_in[MHI:0]),
.dout(misc2[MHI:0])
);
rvdffe #(MSIZE) misc1ff (
.*,
.clk (clk),
.en (qwen[1]),
.din (misc_data_in[MHI:0]),
.dout(misc1[MHI:0])
);
rvdffe #(MSIZE) misc0ff (
.*,
.clk (clk),
.en (qwen[0]),
.din (misc_data_in[MHI:0]),
.dout(misc0[MHI:0])
);
end else begin
rvdffie #((MSIZE*3)+(BRDATA_SIZE*3)) miscff (.*,
.din({qwen[2] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc2[MHI:0], brdata2[BRDATA_SIZE-1:0]},
rvdffie #((MSIZE * 3) + (BRDATA_SIZE * 3)) miscff (
.*,
.din({
qwen[2] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc2[MHI:0], brdata2[BRDATA_SIZE-1:0]},
qwen[1] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc1[MHI:0], brdata1[BRDATA_SIZE-1:0]},
qwen[0] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc0[MHI:0], brdata0[BRDATA_SIZE-1:0]}}),
.dout({misc2[MHI:0], brdata2[BRDATA_SIZE-1:0],
misc1[MHI:0], brdata1[BRDATA_SIZE-1:0],
misc0[MHI:0], brdata0[BRDATA_SIZE-1:0]})
qwen[0] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc0[MHI:0], brdata0[BRDATA_SIZE-1:0]}
}),
.dout({
misc2[MHI:0],
brdata2[BRDATA_SIZE-1:0],
misc1[MHI:0],
brdata1[BRDATA_SIZE-1:0],
misc0[MHI:0],
brdata0[BRDATA_SIZE-1:0]
})
);
end
logic [31:1] q2pc, q1pc, q0pc;
rvdffe #(31) q2pcff (.*, .clk(clk), .en(qwen[2]), .din(ifu_fetch_pc[31:1]), .dout(q2pc[31:1]));
rvdffe #(31) q1pcff (.*, .clk(clk), .en(qwen[1]), .din(ifu_fetch_pc[31:1]), .dout(q1pc[31:1]));
rvdffe #(31) q0pcff (.*, .clk(clk), .en(qwen[0]), .din(ifu_fetch_pc[31:1]), .dout(q0pc[31:1]));
rvdffe #(31) q2pcff (
.*,
.clk (clk),
.en (qwen[2]),
.din (ifu_fetch_pc[31:1]),
.dout(q2pc[31:1])
);
rvdffe #(31) q1pcff (
.*,
.clk (clk),
.en (qwen[1]),
.din (ifu_fetch_pc[31:1]),
.dout(q1pc[31:1])
);
rvdffe #(31) q0pcff (
.*,
.clk (clk),
.en (qwen[0]),
.din (ifu_fetch_pc[31:1]),
.dout(q0pc[31:1])
);
rvdffe #(32) q2ff (.*, .clk(clk), .en(qwen[2]), .din(ifu_fetch_data_f[31:0]), .dout(q2[31:0]));
rvdffe #(32) q1ff (.*, .clk(clk), .en(qwen[1]), .din(ifu_fetch_data_f[31:0]), .dout(q1[31:0]));
rvdffe #(32) q0ff (.*, .clk(clk), .en(qwen[0]), .din(ifu_fetch_data_f[31:0]), .dout(q0[31:0]));
rvdffe #(32) q2ff (
.*,
.clk (clk),
.en (qwen[2]),
.din (ifu_fetch_data_f[31:0]),
.dout(q2[31:0])
);
rvdffe #(32) q1ff (
.*,
.clk (clk),
.en (qwen[1]),
.din (ifu_fetch_data_f[31:0]),
.dout(q1[31:0])
);
rvdffe #(32) q0ff (
.*,
.clk (clk),
.en (qwen[0]),
.din (ifu_fetch_data_f[31:0]),
.dout(q0[31:0])
);
// new queue control logic
assign qren[2:0] = { rdptr[1:0] == 2'b10,
rdptr[1:0] == 2'b01,
rdptr[1:0] == 2'b00 };
assign qren[2:0] = {rdptr[1:0] == 2'b10, rdptr[1:0] == 2'b01, rdptr[1:0] == 2'b00};
assign qwen[2:0] = { (wrptr[1:0] == 2'b10) & ifvalid,
assign qwen[2:0] = {
(wrptr[1:0] == 2'b10) & ifvalid,
(wrptr[1:0] == 2'b01) & ifvalid,
(wrptr[1:0] == 2'b00) & ifvalid };
(wrptr[1:0] == 2'b00) & ifvalid
};
assign rdptr_in[1:0] = ({2{ qren[0] & ifu_fb_consume1 & ~exu_flush_final}} & 2'b01 ) |
@ -311,10 +398,7 @@ end
ifu_bp_poffset_f[11:0],
ifu_bp_fghr_f[pt.BHT_GHR_SIZE-1:0]
};
else
assign misc_data_in[MHI:0] = {
ic_access_fault_type_f[1:0]
};
else assign misc_data_in[MHI:0] = {ic_access_fault_type_f[1:0]};
assign {misc1eff[MHI:0],misc0eff[MHI:0]} = (({MSIZE*2{qren[0]}} & {misc1[MHI:0],misc0[MHI:0]}) |
@ -338,8 +422,24 @@ end
if (pt.BTB_FULLYA) begin
assign brdata_in[BRDATA_SIZE-1:0] = {
ifu_bp_fa_index_f[1], iccm_rd_ecc_double_err[1],ic_access_fault_f[1],ifu_bp_hist1_f[1],ifu_bp_hist0_f[1],ifu_bp_pc4_f[1],ifu_bp_way_f[1],ifu_bp_valid_f[1],ifu_bp_ret_f[1],
ifu_bp_fa_index_f[0], iccm_rd_ecc_double_err[0],ic_access_fault_f[0],ifu_bp_hist1_f[0],ifu_bp_hist0_f[0],ifu_bp_pc4_f[0],ifu_bp_way_f[0],ifu_bp_valid_f[0],ifu_bp_ret_f[0]
ifu_bp_fa_index_f[1],
iccm_rd_ecc_double_err[1],
ic_access_fault_f[1],
ifu_bp_hist1_f[1],
ifu_bp_hist0_f[1],
ifu_bp_pc4_f[1],
ifu_bp_way_f[1],
ifu_bp_valid_f[1],
ifu_bp_ret_f[1],
ifu_bp_fa_index_f[0],
iccm_rd_ecc_double_err[0],
ic_access_fault_f[0],
ifu_bp_hist1_f[0],
ifu_bp_hist0_f[0],
ifu_bp_pc4_f[0],
ifu_bp_way_f[0],
ifu_bp_valid_f[0],
ifu_bp_ret_f[0]
};
assign {f0index[1],f0dbecc[1],f0icaf[1],f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1],
f0index[0],f0dbecc[0],f0icaf[0],f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0]} = brdata0final[BRDATA_SIZE-1:0];
@ -347,11 +447,24 @@ end
assign {f1index[1],f1dbecc[1],f1icaf[1],f1hist1[1],f1hist0[1],f1pc4[1],f1way[1],f1brend[1],f1ret[1],
f1index[0],f1dbecc[0],f1icaf[0],f1hist1[0],f1hist0[0],f1pc4[0],f1way[0],f1brend[0],f1ret[0]} = brdata1final[BRDATA_SIZE-1:0];
end
else begin
end else begin
assign brdata_in[BRDATA_SIZE-1:0] = {
iccm_rd_ecc_double_err[1],ic_access_fault_f[1],ifu_bp_hist1_f[1],ifu_bp_hist0_f[1],ifu_bp_pc4_f[1],ifu_bp_way_f[1],ifu_bp_valid_f[1],ifu_bp_ret_f[1],
iccm_rd_ecc_double_err[0],ic_access_fault_f[0],ifu_bp_hist1_f[0],ifu_bp_hist0_f[0],ifu_bp_pc4_f[0],ifu_bp_way_f[0],ifu_bp_valid_f[0],ifu_bp_ret_f[0]
iccm_rd_ecc_double_err[1],
ic_access_fault_f[1],
ifu_bp_hist1_f[1],
ifu_bp_hist0_f[1],
ifu_bp_pc4_f[1],
ifu_bp_way_f[1],
ifu_bp_valid_f[1],
ifu_bp_ret_f[1],
iccm_rd_ecc_double_err[0],
ic_access_fault_f[0],
ifu_bp_hist1_f[0],
ifu_bp_hist0_f[0],
ifu_bp_pc4_f[0],
ifu_bp_way_f[0],
ifu_bp_valid_f[0],
ifu_bp_ret_f[0]
};
assign {f0dbecc[1],f0icaf[1],f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1],
f0dbecc[0],f0icaf[0],f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0]} = brdata0final[BRDATA_SIZE-1:0];
@ -376,23 +489,19 @@ end
end // if (pt.BTB_ENABLE==1)
else begin
assign {
f1ictype[1:0]
} = misc1eff[MHI:0];
assign {f1ictype[1:0]} = misc1eff[MHI:0];
assign {
f0ictype[1:0]
} = misc0eff[MHI:0];
assign {f0ictype[1:0]} = misc0eff[MHI:0];
assign brdata_in[BRDATA_SIZE-1:0] = {
iccm_rd_ecc_double_err[1],ic_access_fault_f[1],
iccm_rd_ecc_double_err[0],ic_access_fault_f[0]
iccm_rd_ecc_double_err[1],
ic_access_fault_f[1],
iccm_rd_ecc_double_err[0],
ic_access_fault_f[0]
};
assign {f0dbecc[1],f0icaf[1],
f0dbecc[0],f0icaf[0]} = brdata0final[BRDATA_SIZE-1:0];
assign {f0dbecc[1], f0icaf[1], f0dbecc[0], f0icaf[0]} = brdata0final[BRDATA_SIZE-1:0];
assign {f1dbecc[1],f1icaf[1],
f1dbecc[0],f1icaf[0]} = brdata1final[BRDATA_SIZE-1:0];
assign {f1dbecc[1], f1icaf[1], f1dbecc[0], f1icaf[0]} = brdata1final[BRDATA_SIZE-1:0];
assign {brdata1eff[BRDATA_SIZE-1:0],brdata0eff[BRDATA_SIZE-1:0]} = (({BRDATA_SIZE*2{qren[0]}} & {brdata1[BRDATA_SIZE-1:0],brdata0[BRDATA_SIZE-1:0]}) |
({BRDATA_SIZE*2{qren[1]}} & {brdata2[BRDATA_SIZE-1:0],brdata1[BRDATA_SIZE-1:0]}) |
@ -451,8 +560,7 @@ end
({2{~fetch_to_f2 & ~shift_f2_f1 & ~shift_f2_f0 & ~exu_flush_final}} & f2val[1:0] );
assign sf1val[1:0] = ({2{ f1_shift_2B}} & {1'b0,f1val[1]}) |
({2{~f1_shift_2B}} & f1val[1:0] );
assign sf1val[1:0] = ({2{f1_shift_2B}} & {1'b0, f1val[1]}) | ({2{~f1_shift_2B}} & f1val[1:0]);
assign f1val_in[1:0] = ({2{ fetch_to_f1 & ~exu_flush_final}} & ifu_fetch_val[1:0]) |
({2{ shift_f2_f1 & ~exu_flush_final}} & f2val[1:0] ) |
@ -475,8 +583,7 @@ end
assign q0final[31:0] = ({32{q0sel[0]}} & { q0eff[31:0]}) |
({32{q0sel[1]}} & {16'b0,q0eff[31:16]});
assign q1final[15:0] = ({16{q1sel[0]}} & q1eff[15:0] ) |
({16{q1sel[1]}} & q1eff[31:16]);
assign q1final[15:0] = ({16{q1sel[0]}} & q1eff[15:0]) | ({16{q1sel[1]}} & q1eff[31:16]);
logic [31:1] q0pceff, q0pcfinal;
logic [31:1] q1pceff;
@ -491,8 +598,7 @@ end
assign aligndata[31:0] = ({32{ f0val[1] }} & {q0final[31:0]}) |
({32{~f0val[1] & f0val[0]}} & {q1final[15:0],q0final[15:0]});
assign alignval[1:0] = ({ 2{ f0val[1] }} & {2'b11}) |
({ 2{~f0val[1] & f0val[0]}} & {f1val[0],1'b1});
assign alignval[1:0] = ({2{f0val[1]}} & {2'b11}) | ({2{~f0val[1] & f0val[0]}} & {f1val[0], 1'b1});
assign alignicaf[1:0] = ({ 2{ f0val[1] }} & f0icaf[1:0] ) |
({ 2{~f0val[1] & f0val[0]}} & {f1icaf[0],f0icaf[0]});
@ -549,12 +655,10 @@ end
assign first4B = (aligndata[1:0] == 2'b11);
assign first2B = ~first4B;
assign ifu_i0_valid = (first4B & alignval[1]) |
(first2B & alignval[0]);
assign ifu_i0_valid = (first4B & alignval[1]) | (first2B & alignval[0]);
// inst access fault on any byte of inst results in access fault for the inst
assign ifu_i0_icaf = (first4B & (|alignicaf[1:0])) |
(first2B & alignicaf[0] );
assign ifu_i0_icaf = (first4B & (|alignicaf[1:0])) | (first2B & alignicaf[0]);
assign ifu_i0_icaf_type[1:0] = (first4B & ~f0val[1] & f0val[0] & ~alignicaf[0] & ~aligndbecc[0]) ? f1ictype[1:0] : f0ictype[1:0];
@ -563,8 +667,7 @@ end
assign ifu_i0_icaf_second = first4B & ~icaf_eff[0] & icaf_eff[1];
assign ifu_i0_dbecc = (first4B & (|aligndbecc[1:0])) |
(first2B & aligndbecc[0] );
assign ifu_i0_dbecc = (first4B & (|aligndbecc[1:0])) | (first2B & aligndbecc[0]);
assign ifirst[31:0] = aligndata[31:0];
@ -577,27 +680,49 @@ if(pt.BTB_ENABLE==1) begin
// if you detect br does not start on instruction boundary
el2_btb_addr_hash #(.pt(pt)) firsthash (.pc(firstpc [pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
.hash(firstpc_hash [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
el2_btb_addr_hash #(.pt(pt)) secondhash(.pc(secondpc[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
.hash(secondpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
el2_btb_addr_hash #(
.pt(pt)
) firsthash (
.pc (firstpc[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
.hash(firstpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO])
);
el2_btb_addr_hash #(
.pt(pt)
) secondhash (
.pc (secondpc[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
.hash(secondpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO])
);
if (pt.BTB_FULLYA) begin
assign firstbrtag_hash = firstpc;
assign secondbrtag_hash = secondpc;
end
else begin
end else begin
if (pt.BTB_BTAG_FOLD) begin : btbfold
el2_btb_tag_hash_fold #(.pt(pt)) first_brhash (.pc(firstpc [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
.hash(firstbrtag_hash [pt.BTB_BTAG_SIZE-1:0]));
el2_btb_tag_hash_fold #(.pt(pt)) second_brhash(.pc(secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
.hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0]));
end
else begin
el2_btb_tag_hash #(.pt(pt)) first_brhash (.pc(firstpc [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
.hash(firstbrtag_hash [pt.BTB_BTAG_SIZE-1:0]));
el2_btb_tag_hash #(.pt(pt)) second_brhash(.pc(secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
.hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0]));
el2_btb_tag_hash_fold #(
.pt(pt)
) first_brhash (
.pc (firstpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
.hash(firstbrtag_hash[pt.BTB_BTAG_SIZE-1:0])
);
el2_btb_tag_hash_fold #(
.pt(pt)
) second_brhash (
.pc (secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
.hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0])
);
end else begin
el2_btb_tag_hash #(
.pt(pt)
) first_brhash (
.pc(firstpc [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
.hash(firstbrtag_hash[pt.BTB_BTAG_SIZE-1:0])
);
el2_btb_tag_hash #(
.pt(pt)
) second_brhash (
.pc(secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
.hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0])
);
end
end // else: !if(pt.BTB_FULLYA)
@ -611,23 +736,17 @@ if(pt.BTB_ENABLE==1) begin
i0_br_start_error = (first4B & alignval[1] & alignbrend[0]);
i0_brp.valid = (first2B & alignbrend[0]) |
(first4B & alignbrend[1]) |
i0_br_start_error;
i0_brp.valid = (first2B & alignbrend[0]) | (first4B & alignbrend[1]) | i0_br_start_error;
i0_brp_pc4 = (first2B & alignpc4[0]) |
(first4B & alignpc4[1]);
i0_brp_pc4 = (first2B & alignpc4[0]) | (first4B & alignpc4[1]);
i0_brp.ret = (first2B & alignret[0]) |
(first4B & alignret[1]);
i0_brp.ret = (first2B & alignret[0]) | (first4B & alignret[1]);
i0_brp.way = (first2B | alignbrend[0]) ? alignway[0] : alignway[1];
i0_brp.hist[1] = (first2B & alignhist1[0]) |
(first4B & alignhist1[1]);
i0_brp.hist[1] = (first2B & alignhist1[0]) | (first4B & alignhist1[1]);
i0_brp.hist[0] = (first2B & alignhist0[0]) |
(first4B & alignhist0[1]);
i0_brp.hist[0] = (first2B & alignhist0[0]) | (first4B & alignhist0[1]);
i0_ends_f1 = first4B & alignfromf1[1];
@ -644,8 +763,7 @@ if(pt.BTB_ENABLE==1) begin
if (pt.BTB_FULLYA)
ifu_i0_fa_index = (first2B | alignbrend[0]) ? alignindex[0] : alignindex[1];
else
ifu_i0_fa_index = '0;
else ifu_i0_fa_index = '0;
end
@ -658,8 +776,7 @@ if(pt.BTB_ENABLE==1) begin
assign ifu_i0_bp_btag[pt.BTB_BTAG_SIZE-1:0] = (first2B | alignbrend[0]) ? firstbrtag_hash[pt.BTB_BTAG_SIZE-1:0] :
secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0];
end
else begin
end else begin
assign i0_brp = '0;
assign ifu_i0_bp_index = '0;
assign ifu_i0_bp_fghr = '0;
@ -669,7 +786,10 @@ end // else: !if(pt.BTB_ENABLE==1)
// decompress
// quiet inputs for 4B inst
el2_ifu_compress_ctl compress0 (.din((first2B) ? aligndata[15:0] : '0), .dout(uncompress0[31:0]));
el2_ifu_compress_ctl compress0 (
.din ((first2B) ? aligndata[15:0] : '0),
.dout(uncompress0[31:0])
);
@ -685,8 +805,7 @@ end // else: !if(pt.BTB_ENABLE==1)
assign shift_4B = i0_shift & first4B;
// exact equations for the queue logic
assign f0_shift_2B = (shift_2B & f0val[0] ) |
(shift_4B & f0val[0] & ~f0val[1]);
assign f0_shift_2B = (shift_2B & f0val[0]) | (shift_4B & f0val[0] & ~f0val[1]);
// f0 valid states

View File

@ -28,8 +28,7 @@ module el2_ifu_bp_ctl
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk,
input logic rst_l,
@ -43,7 +42,9 @@ import el2_pkg::*;
input logic [pt.BHT_GHR_SIZE-1:0] exu_i0_br_fghr_r, // fghr to bp
input logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] exu_i0_br_index_r, // bp index
input logic [$clog2(pt.BTB_SIZE)-1:0] dec_fa_error_index, // Fully associative btb error index
input logic [$clog2(
pt.BTB_SIZE
)-1:0] dec_fa_error_index, // Fully associative btb error index
input logic dec_tlu_flush_lower_wb, // used to move EX4 RS to EX1 and F
input logic dec_tlu_flush_leak_one_wb, // don't hit for leak one fetches
@ -73,7 +74,9 @@ import el2_pkg::*;
output logic [1:0] ifu_bp_valid_f, // branch valid, right justified
output logic [11:0] ifu_bp_poffset_f, // predicted target
output logic [1:0] [$clog2(pt.BTB_SIZE)-1:0] ifu_bp_fa_index_f, // predicted branch index (fully associative option)
output logic [1:0][$clog2(
pt.BTB_SIZE
)-1:0] ifu_bp_fa_index_f, // predicted branch index (fully associative option)
input logic scan_mode
);
@ -139,14 +142,25 @@ import el2_pkg::*;
logic dec_tlu_error_wb, btb_valid, dec_tlu_br0_middle_wb;
logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] btb_error_addr_wb;
logic branch_error_collision_f, fetch_mp_collision_f, branch_error_collision_p1_f, fetch_mp_collision_p1_f;
logic
branch_error_collision_f,
fetch_mp_collision_f,
branch_error_collision_p1_f,
fetch_mp_collision_p1_f;
logic branch_error_bank_conflict_f;
logic [pt.BHT_GHR_SIZE-1:0] merged_ghr, fghr_ns, fghr;
logic [1:0] num_valids;
logic [LRU_SIZE-1:0] btb_lru_b0_f, btb_lru_b0_hold, btb_lru_b0_ns,
fetch_wrindex_dec, fetch_wrindex_p1_dec, fetch_wrlru_b0, fetch_wrlru_p1_b0,
mp_wrindex_dec, mp_wrlru_b0;
logic [LRU_SIZE-1:0]
btb_lru_b0_f,
btb_lru_b0_hold,
btb_lru_b0_ns,
fetch_wrindex_dec,
fetch_wrindex_p1_dec,
fetch_wrlru_b0,
fetch_wrlru_p1_b0,
mp_wrindex_dec,
mp_wrlru_b0;
logic btb_lru_rd_f, btb_lru_rd_p1_f, lru_update_valid_f;
logic tag_match_way0_f, tag_match_way1_f;
logic [1:0] way_raw, bht_dir_f, btb_sel_f, wayhit_f, vwayhit_f, wayhit_p1_f;
@ -175,7 +189,12 @@ import el2_pkg::*;
logic branch_error_bank_conflict_p1_f;
logic tag_match_way0_p1_f, tag_match_way1_p1_f;
logic [1:0] btb_vlru_rd_f, fetch_start_f, tag_match_vway1_expanded_f, tag_match_way0_expanded_p1_f, tag_match_way1_expanded_p1_f;
logic [1:0]
btb_vlru_rd_f,
fetch_start_f,
tag_match_vway1_expanded_f,
tag_match_way0_expanded_p1_f,
tag_match_way1_expanded_p1_f;
logic [31:2] fetch_addr_p1_f;
@ -222,11 +241,21 @@ import el2_pkg::*;
// ----------------------------------------------------------------------
// hash the incoming fetch PC, first guess at hashing algorithm
el2_btb_addr_hash #(.pt(pt)) f1hash(.pc(ifc_fetch_addr_f[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]), .hash(btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
el2_btb_addr_hash #(
.pt(pt)
) f1hash (
.pc (ifc_fetch_addr_f[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
.hash(btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO])
);
assign fetch_addr_p1_f[31:2] = ifc_fetch_addr_f[31:2] + 30'b1;
el2_btb_addr_hash #(.pt(pt)) f1hash_p1(.pc(fetch_addr_p1_f[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]), .hash(btb_rd_addr_p1_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
el2_btb_addr_hash #(
.pt(pt)
) f1hash_p1 (
.pc (fetch_addr_p1_f[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
.hash(btb_rd_addr_p1_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO])
);
assign btb_sel_f[1] = ~bht_dir_f[0];
assign btb_sel_f[0] = bht_dir_f[0];
@ -271,17 +300,25 @@ logic exu_flush_final_d1;
// Both ways could hit, use the offset bit to reorder
assign tag_match_way0_expanded_f[1:0] = {tag_match_way0_f & (btb_bank0_rd_data_way0_f[BOFF] ^ btb_bank0_rd_data_way0_f[PC4]),
tag_match_way0_f & ~(btb_bank0_rd_data_way0_f[BOFF] ^ btb_bank0_rd_data_way0_f[PC4])};
assign tag_match_way0_expanded_f[1:0] = {
tag_match_way0_f & (btb_bank0_rd_data_way0_f[BOFF] ^ btb_bank0_rd_data_way0_f[PC4]),
tag_match_way0_f & ~(btb_bank0_rd_data_way0_f[BOFF] ^ btb_bank0_rd_data_way0_f[PC4])
};
assign tag_match_way1_expanded_f[1:0] = {tag_match_way1_f & (btb_bank0_rd_data_way1_f[BOFF] ^ btb_bank0_rd_data_way1_f[PC4]),
tag_match_way1_f & ~(btb_bank0_rd_data_way1_f[BOFF] ^ btb_bank0_rd_data_way1_f[PC4])};
assign tag_match_way1_expanded_f[1:0] = {
tag_match_way1_f & (btb_bank0_rd_data_way1_f[BOFF] ^ btb_bank0_rd_data_way1_f[PC4]),
tag_match_way1_f & ~(btb_bank0_rd_data_way1_f[BOFF] ^ btb_bank0_rd_data_way1_f[PC4])
};
assign tag_match_way0_expanded_p1_f[1:0] = {tag_match_way0_p1_f & (btb_bank0_rd_data_way0_p1_f[BOFF] ^ btb_bank0_rd_data_way0_p1_f[PC4]),
tag_match_way0_p1_f & ~(btb_bank0_rd_data_way0_p1_f[BOFF] ^ btb_bank0_rd_data_way0_p1_f[PC4])};
assign tag_match_way0_expanded_p1_f[1:0] = {
tag_match_way0_p1_f & (btb_bank0_rd_data_way0_p1_f[BOFF] ^ btb_bank0_rd_data_way0_p1_f[PC4]),
tag_match_way0_p1_f & ~(btb_bank0_rd_data_way0_p1_f[BOFF] ^ btb_bank0_rd_data_way0_p1_f[PC4])
};
assign tag_match_way1_expanded_p1_f[1:0] = {tag_match_way1_p1_f & (btb_bank0_rd_data_way1_p1_f[BOFF] ^ btb_bank0_rd_data_way1_p1_f[PC4]),
tag_match_way1_p1_f & ~(btb_bank0_rd_data_way1_p1_f[BOFF] ^ btb_bank0_rd_data_way1_p1_f[PC4])};
assign tag_match_way1_expanded_p1_f[1:0] = {
tag_match_way1_p1_f & (btb_bank0_rd_data_way1_p1_f[BOFF] ^ btb_bank0_rd_data_way1_p1_f[PC4]),
tag_match_way1_p1_f & ~(btb_bank0_rd_data_way1_p1_f[BOFF] ^ btb_bank0_rd_data_way1_p1_f[PC4])
};
assign wayhit_f[1:0] = tag_match_way0_expanded_f[1:0] | tag_match_way1_expanded_f[1:0];
assign wayhit_p1_f[1:0] = tag_match_way0_expanded_p1_f[1:0] | tag_match_way1_expanded_p1_f[1:0];
@ -351,9 +388,12 @@ logic exu_flush_final_d1;
({2{fetch_start_f[1]}} & {tag_match_way1_expanded_p1_f[0], tag_match_way1_expanded_f[1]}) );
rvdffe #(LRU_SIZE) btb_lru_ff (.*, .en(ifc_fetch_req_f | exu_mp_valid),
rvdffe #(LRU_SIZE) btb_lru_ff (
.*,
.en (ifc_fetch_req_f | exu_mp_valid),
.din (btb_lru_b0_ns[(LRU_SIZE)-1:0]),
.dout(btb_lru_b0_f[(LRU_SIZE)-1:0]));
.dout(btb_lru_b0_f[(LRU_SIZE)-1:0])
);
end // if (!pt.BTB_FULLYA)
// Detect end of cache line and mask as needed
@ -387,8 +427,10 @@ logic exu_flush_final_d1;
// Don't put calls/rets/ja in the predictor, force the bht taken instead
assign bht_force_taken_f[1:0] = {(btb_vbank1_rd_data_f[CALL] | btb_vbank1_rd_data_f[RET]),
(btb_vbank0_rd_data_f[CALL] | btb_vbank0_rd_data_f[RET])};
assign bht_force_taken_f[1:0] = {
(btb_vbank1_rd_data_f[CALL] | btb_vbank1_rd_data_f[RET]),
(btb_vbank0_rd_data_f[CALL] | btb_vbank0_rd_data_f[RET])
};
// taken and valid, otherwise, branch errors must clear the bht
@ -401,8 +443,10 @@ logic exu_flush_final_d1;
({2{fetch_start_f[1]}} & bht_bank0_rd_data_p1_f[1:0]) );
assign bht_dir_f[1:0] = {(bht_force_taken_f[1] | bht_vbank1_rd_data_f[1]) & bht_valid_f[1],
(bht_force_taken_f[0] | bht_vbank0_rd_data_f[1]) & bht_valid_f[0]};
assign bht_dir_f[1:0] = {
(bht_force_taken_f[1] | bht_vbank1_rd_data_f[1]) & bht_valid_f[1],
(bht_force_taken_f[0] | bht_vbank0_rd_data_f[1]) & bht_valid_f[0]
};
assign ifu_bp_inst_mask_f = (ifu_bp_hit_taken_f & btb_sel_f[1]) | ~ifu_bp_hit_taken_f;
@ -427,15 +471,17 @@ logic exu_flush_final_d1;
assign hist1_raw[1:0] = bht_force_taken_f[1:0] | {bht_vbank1_rd_data_f[1],
bht_vbank0_rd_data_f[1]};
assign hist0_raw[1:0] = {bht_vbank1_rd_data_f[0],
bht_vbank0_rd_data_f[0]};
assign hist0_raw[1:0] = {bht_vbank1_rd_data_f[0], bht_vbank0_rd_data_f[0]};
assign pc4_raw[1:0] = {vwayhit_f[1] & btb_vbank1_rd_data_f[PC4],
vwayhit_f[0] & btb_vbank0_rd_data_f[PC4]};
assign pc4_raw[1:0] = {
vwayhit_f[1] & btb_vbank1_rd_data_f[PC4], vwayhit_f[0] & btb_vbank0_rd_data_f[PC4]
};
assign pret_raw[1:0] = {vwayhit_f[1] & ~btb_vbank1_rd_data_f[CALL] & btb_vbank1_rd_data_f[RET],
vwayhit_f[0] & ~btb_vbank0_rd_data_f[CALL] & btb_vbank0_rd_data_f[RET]};
assign pret_raw[1:0] = {
vwayhit_f[1] & ~btb_vbank1_rd_data_f[CALL] & btb_vbank1_rd_data_f[RET],
vwayhit_f[0] & ~btb_vbank0_rd_data_f[CALL] & btb_vbank0_rd_data_f[RET]
};
// GHR
@ -464,9 +510,14 @@ logic exu_flush_final_d1;
({pt.BHT_GHR_SIZE{~exu_flush_final_d1 & ifc_fetch_req_f & ic_hit_f & ~leak_one_f_d1}} & merged_ghr[pt.BHT_GHR_SIZE-1:0]) |
({pt.BHT_GHR_SIZE{~exu_flush_final_d1 & ~(ifc_fetch_req_f & ic_hit_f & ~leak_one_f_d1)}} & fghr[pt.BHT_GHR_SIZE-1:0]));
rvdffie #(.WIDTH(pt.BHT_GHR_SIZE+3),.OVERRIDE(1)) fetchghr (.*,
rvdffie #(
.WIDTH(pt.BHT_GHR_SIZE + 3),
.OVERRIDE(1)
) fetchghr (
.*,
.din ({exu_flush_final, exu_mp_way, leak_one_f, fghr_ns[pt.BHT_GHR_SIZE-1:0]}),
.dout({exu_flush_final_d1, exu_mp_way_f, leak_one_f_d1, fghr[pt.BHT_GHR_SIZE-1:0]}));
.dout({exu_flush_final_d1, exu_mp_way_f, leak_one_f_d1, fghr[pt.BHT_GHR_SIZE-1:0]})
);
assign ifu_bp_fghr_f[pt.BHT_GHR_SIZE-1:0] = fghr[pt.BHT_GHR_SIZE-1:0];
@ -499,10 +550,8 @@ logic exu_flush_final_d1;
// 10 10 1 01 0
logic [1:0] bloc_f;
logic use_fa_plus;
assign bloc_f[1] = (bht_dir_f[0] & ~fetch_start_f[0]) | (~bht_dir_f[0]
& fetch_start_f[0]);
assign bloc_f[0] = (bht_dir_f[0] & fetch_start_f[0]) | (~bht_dir_f[0]
& ~fetch_start_f[0]);
assign bloc_f[1] = (bht_dir_f[0] & ~fetch_start_f[0]) | (~bht_dir_f[0] & fetch_start_f[0]);
assign bloc_f[0] = (bht_dir_f[0] & fetch_start_f[0]) | (~bht_dir_f[0] & ~fetch_start_f[0]);
assign use_fa_plus = (~bht_dir_f[0] & ~fetch_start_f[0] & ~btb_rd_pc4_f);
@ -513,7 +562,15 @@ assign use_fa_plus = (~bht_dir_f[0] & ~fetch_start_f[0] & ~btb_rd_pc4_f);
assign bp_total_branch_offset_f = bloc_f[1] ^ btb_rd_pc4_f;
logic [31:2] adder_pc_in_f, ifc_fetch_adder_prior;
rvdfflie #(.WIDTH(30), .LEFT(19)) faddrf_ff (.*, .en(ifc_fetch_req_f & ~ifu_bp_hit_taken_f & ic_hit_f), .din(ifc_fetch_addr_f[31:2]), .dout(ifc_fetch_adder_prior[31:2]));
rvdfflie #(
.WIDTH(30),
.LEFT (19)
) faddrf_ff (
.*,
.en (ifc_fetch_req_f & ~ifu_bp_hit_taken_f & ic_hit_f),
.din (ifc_fetch_addr_f[31:2]),
.dout(ifc_fetch_adder_prior[31:2])
);
assign ifu_bp_poffset_f[11:0] = btb_rd_tgt_f[11:0];
@ -522,7 +579,8 @@ assign use_fa_plus = (~bht_dir_f[0] & ~fetch_start_f[0] & ~btb_rd_pc4_f);
({30{ btb_fg_crossing_f}} & ifc_fetch_adder_prior[31:2]) |
({30{~btb_fg_crossing_f & ~use_fa_plus}} & ifc_fetch_addr_f[31:2]));
rvbradder predtgt_addr (.pc({adder_pc_in_f[31:2], bp_total_branch_offset_f}),
rvbradder predtgt_addr (
.pc({adder_pc_in_f[31:2], bp_total_branch_offset_f}),
.offset(btb_rd_tgt_f[11:0]),
.dout(bp_btb_target_adder_f[31:1])
);
@ -535,7 +593,8 @@ assign use_fa_plus = (~bht_dir_f[0] & ~fetch_start_f[0] & ~btb_rd_pc4_f);
// Return Stack
// ----------------------------------------------------------------------
rvbradder rs_addr (.pc({adder_pc_in_f[31:2], bp_total_branch_offset_f}),
rvbradder rs_addr (
.pc({adder_pc_in_f[31:2], bp_total_branch_offset_f}),
.offset({11'b0, ~btb_rd_pc4_f}),
.dout(bp_rs_call_target_f[31:1])
);
@ -558,13 +617,17 @@ assign use_fa_plus = (~bht_dir_f[0] & ~fetch_start_f[0] & ~btb_rd_pc4_f);
if (i == pt.RET_STACK_SIZE - 1) begin
assign rets_in[i][31:0] = rets_out[i-1][31:0];
assign rsenable[i] = rs_push;
end
else if(i>0) begin
end else if (i > 0) begin
assign rets_in[i][31:0] = ( ({32{rs_push}} & rets_out[i-1][31:0]) |
({32{rs_pop}} & rets_out[i+1][31:0]) );
assign rsenable[i] = rs_push | rs_pop;
end
rvdffe #(32) rets_ff (.*, .en(rsenable[i]), .din(rets_in[i][31:0]), .dout(rets_out[i][31:0]));
rvdffe #(32) rets_ff (
.*,
.en (rsenable[i]),
.din (rets_in[i][31:0]),
.dout(rets_out[i][31:0])
);
end : retstack
@ -586,16 +649,35 @@ assign use_fa_plus = (~bht_dir_f[0] & ~fetch_start_f[0] & ~btb_rd_pc4_f);
if (!pt.BTB_FULLYA) begin
if (pt.BTB_BTAG_FOLD) begin : btbfold
el2_btb_tag_hash_fold #(.pt(pt)) rdtagf (.hash(fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0]),
.pc({ifc_fetch_addr_f[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]}));
el2_btb_tag_hash_fold #(.pt(pt)) rdtagp1f(.hash(fetch_rd_tag_p1_f[pt.BTB_BTAG_SIZE-1:0]),
.pc({fetch_addr_p1_f[ pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]}));
end
else begin
el2_btb_tag_hash #(.pt(pt)) rdtagf(.hash(fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0]),
.pc({ifc_fetch_addr_f[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]}));
el2_btb_tag_hash #(.pt(pt)) rdtagp1f(.hash(fetch_rd_tag_p1_f[pt.BTB_BTAG_SIZE-1:0]),
.pc({fetch_addr_p1_f[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]}));
el2_btb_tag_hash_fold #(
.pt(pt)
) rdtagf (
.hash(fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0]),
.pc({ifc_fetch_addr_f[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]})
);
el2_btb_tag_hash_fold #(
.pt(pt)
) rdtagp1f (
.hash(fetch_rd_tag_p1_f[pt.BTB_BTAG_SIZE-1:0]),
.pc({fetch_addr_p1_f[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]})
);
end else begin
el2_btb_tag_hash #(
.pt(pt)
) rdtagf (
.hash(fetch_rd_tag_f[pt.BTB_BTAG_SIZE-1:0]),
.pc({
ifc_fetch_addr_f[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]
})
);
el2_btb_tag_hash #(
.pt(pt)
) rdtagp1f (
.hash(fetch_rd_tag_p1_f[pt.BTB_BTAG_SIZE-1:0]),
.pc({
fetch_addr_p1_f[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]
})
);
end
assign btb_wr_en_way0 = ( ({{~exu_mp_way & exu_mp_valid_write & ~dec_tlu_error_wb}}) |
@ -611,8 +693,15 @@ assign use_fa_plus = (~bht_dir_f[0] & ~fetch_start_f[0] & ~btb_rd_pc4_f);
end // if (!pt.BTB_FULLYA)
assign btb_wr_data[BTB_DWIDTH-1:0] = {btb_wr_tag[pt.BTB_BTAG_SIZE-1:0], exu_mp_tgt[pt.BTB_TOFFSET_SIZE-1:0], exu_mp_pc4, exu_mp_boffset,
exu_mp_call | exu_mp_ja, exu_mp_ret | exu_mp_ja, btb_valid} ;
assign btb_wr_data[BTB_DWIDTH-1:0] = {
btb_wr_tag[pt.BTB_BTAG_SIZE-1:0],
exu_mp_tgt[pt.BTB_TOFFSET_SIZE-1:0],
exu_mp_pc4,
exu_mp_boffset,
exu_mp_call | exu_mp_ja,
exu_mp_ret | exu_mp_ja,
btb_valid
};
assign exu_mp_valid_write = exu_mp_valid & exu_mp_ataken & ~exu_mp_pkt.valid;
logic [1:0] bht_wr_data0, bht_wr_data2;
@ -628,13 +717,39 @@ assign use_fa_plus = (~bht_dir_f[0] & ~fetch_start_f[0] & ~btb_rd_pc4_f);
logic [pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] bht_rd_addr_f, bht_rd_addr_p1_f, bht_wr_addr0, bht_wr_addr2;
logic [pt.BHT_ADDR_HI:pt.BHT_ADDR_LO]
bht_rd_addr_f, bht_rd_addr_p1_f, bht_wr_addr0, bht_wr_addr2;
logic [pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] mp_hashed, br0_hashed_wb, bht_rd_addr_hashed_f, bht_rd_addr_hashed_p1_f;
el2_btb_ghr_hash #(.pt(pt)) mpghrhs (.hashin(exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]), .ghr(exu_mp_eghr[pt.BHT_GHR_SIZE-1:0]), .hash(mp_hashed[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO]));
el2_btb_ghr_hash #(.pt(pt)) br0ghrhs (.hashin(dec_tlu_br0_addr_wb[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]), .ghr(exu_i0_br_fghr_wb[pt.BHT_GHR_SIZE-1:0]), .hash(br0_hashed_wb[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO]));
el2_btb_ghr_hash #(.pt(pt)) fghrhs (.hashin(btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]), .ghr(fghr[pt.BHT_GHR_SIZE-1:0]), .hash(bht_rd_addr_hashed_f[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO]));
el2_btb_ghr_hash #(.pt(pt)) fghrhs_p1 (.hashin(btb_rd_addr_p1_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]), .ghr(fghr[pt.BHT_GHR_SIZE-1:0]), .hash(bht_rd_addr_hashed_p1_f[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO]));
logic [pt.BHT_ADDR_HI:pt.BHT_ADDR_LO]
mp_hashed, br0_hashed_wb, bht_rd_addr_hashed_f, bht_rd_addr_hashed_p1_f;
el2_btb_ghr_hash #(
.pt(pt)
) mpghrhs (
.hashin(exu_mp_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]),
.ghr(exu_mp_eghr[pt.BHT_GHR_SIZE-1:0]),
.hash(mp_hashed[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO])
);
el2_btb_ghr_hash #(
.pt(pt)
) br0ghrhs (
.hashin(dec_tlu_br0_addr_wb[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]),
.ghr(exu_i0_br_fghr_wb[pt.BHT_GHR_SIZE-1:0]),
.hash(br0_hashed_wb[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO])
);
el2_btb_ghr_hash #(
.pt(pt)
) fghrhs (
.hashin(btb_rd_addr_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]),
.ghr(fghr[pt.BHT_GHR_SIZE-1:0]),
.hash(bht_rd_addr_hashed_f[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO])
);
el2_btb_ghr_hash #(
.pt(pt)
) fghrhs_p1 (
.hashin(btb_rd_addr_p1_f[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]),
.ghr(fghr[pt.BHT_GHR_SIZE-1:0]),
.hash(bht_rd_addr_hashed_p1_f[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO])
);
assign bht_wr_addr0[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = mp_hashed[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO];
assign bht_wr_addr2[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = br0_hashed_wb[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO];
@ -652,16 +767,20 @@ assign use_fa_plus = (~bht_dir_f[0] & ~fetch_start_f[0] & ~btb_rd_pc4_f);
for (j = 0; j < LRU_SIZE; j++) begin : BTB_FLOPS
// Way 0
rvdffe #(17+pt.BTB_BTAG_SIZE) btb_bank0_way0 (.*,
rvdffe #(17 + pt.BTB_BTAG_SIZE) btb_bank0_way0 (
.*,
.en (((btb_wr_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] == j) & btb_wr_en_way0)),
.din (btb_wr_data[BTB_DWIDTH-1:0]),
.dout (btb_bank0_rd_data_way0_out[j]));
.dout(btb_bank0_rd_data_way0_out[j])
);
// Way 1
rvdffe #(17+pt.BTB_BTAG_SIZE) btb_bank0_way1 (.*,
rvdffe #(17 + pt.BTB_BTAG_SIZE) btb_bank0_way1 (
.*,
.en (((btb_wr_addr[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] == j) & btb_wr_en_way1)),
.din (btb_wr_data[BTB_DWIDTH-1:0]),
.dout (btb_bank0_rd_data_way1_out[j]));
.dout(btb_bank0_rd_data_way1_out[j])
);
end
@ -701,8 +820,8 @@ end // if (!pt.BTB_FULLYA)
logic btb_used_reset, write_used;
logic [$clog2(pt.BTB_SIZE)-1:0] btb_fa_wr_addr0, hit0_index, hit1_index;
logic [pt.BTB_SIZE-1:0] btb_tag_hit, btb_offset_0, btb_offset_1, btb_used_ns, btb_used,
wr0_en, btb_upper_hit;
logic [pt.BTB_SIZE-1:0]
btb_tag_hit, btb_offset_0, btb_offset_1, btb_used_ns, btb_used, wr0_en, btb_upper_hit;
logic [pt.BTB_SIZE-1:0][BTB_DWIDTH-1:0] btbdata;
// Fully Associative tag hash uses bits 31:3. Bits 2:1 are the offset bits used for the 4 tag comp banks
@ -788,10 +907,13 @@ end // if (!pt.BTB_FULLYA)
assign wr0_en[j] = ((btb_fa_wr_addr0[BTB_FA_INDEX:0] == j) & (exu_mp_valid_write & ~exu_mp_pkt.way)) |
((dec_fa_error_index == j) & dec_tlu_error_wb);
rvdffe #(BTB_DWIDTH) btb_fa (.*, .clk(clk),
rvdffe #(BTB_DWIDTH) btb_fa (
.*,
.clk (clk),
.en (wr0_en[j]),
.din (btb_wr_data[BTB_DWIDTH-1:0]),
.dout(btbdata[j]));
.dout(btbdata[j])
);
end // block: BTB_FAFLOPS
assign ifu_bp_fa_index_f[1] = hit1 ? hit1_index : '0;
@ -808,10 +930,13 @@ end // if (!pt.BTB_FULLYA)
assign write_used = btb_used_reset | ifu_bp_hit_taken_f | exu_mp_valid_write | dec_tlu_error_wb;
rvdffe #(pt.BTB_SIZE) btb_usedf (.*, .clk(clk),
rvdffe #(pt.BTB_SIZE) btb_usedf (
.*,
.clk (clk),
.en (write_used),
.din (btb_used_ns[pt.BTB_SIZE-1:0]),
.dout(btb_used[pt.BTB_SIZE-1:0]));
.dout(btb_used[pt.BTB_SIZE-1:0])
);
end // block: fa
@ -836,7 +961,11 @@ end // block: fa
assign bht_bank_clken[i][k] = (bht_wr_en0[i] & ((bht_wr_addr0[pt.BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)) |
(bht_wr_en2[i] & ((bht_wr_addr2[pt.BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH));
rvclkhdr bht_bank_grp_cgc ( .en(bht_bank_clken[i][k]), .l1clk(bht_bank_clk[i][k]), .* );
rvclkhdr bht_bank_grp_cgc (
.en(bht_bank_clken[i][k]),
.l1clk(bht_bank_clk[i][k]),
.*
);
for (j = 0; j < NUM_BHT_LOOP; j++) begin : BHT_FLOPS
wire [1:0] wdata;
@ -851,13 +980,15 @@ end // block: fa
rvdffs_fpga #(2) bht_bank (.*,
rvdffs_fpga #(2) bht_bank (
.*,
.clk (bht_bank_clk[i][k]),
.en (bank_sel),
.rawclk(clk),
.clken (bank_sel),
.din (wdata),
.dout (bht_bank_rd_data_out[i][(16*k)+j]));
.dout (bht_bank_rd_data_out[i][(16*k)+j])
);
end // block: BHT_FLOPS
end // block: BHT_CLK_GROUP
@ -884,8 +1015,7 @@ function [1:0] countones;
begin
countones[1:0] = {2'b0, valid[1]} +
{2'b0, valid[0]};
countones[1:0] = {2'b0, valid[1]} + {2'b0, valid[0]};
end
endfunction
endmodule // el2_ifu_bp_ctl

View File

@ -21,8 +21,7 @@ module el2_ifu_compress_ctl
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic [15:0] din, // 16-bit compressed instruction
output logic [31:0] dout // 32-bit uncompressed instruction
);
@ -106,9 +105,7 @@ import el2_pkg::*;
// rs2
assign l1[24:20] = o[24:20] |
({5{rs2rs2}} & rs2d[4:0]) |
({5{rs2prs2}} & rs2pd[4:0]);
assign l1[24:20] = o[24:20] | ({5{rs2rs2}} & rs2d[4:0]) | ({5{rs2prs2}} & rs2pd[4:0]);
assign l1[31:25] = o[31:25];

View File

@ -21,8 +21,7 @@ module el2_ifu_ic_mem
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
input logic rst_l, // reset, active low
@ -60,16 +59,18 @@ import el2_pkg::*;
EL2_IC_TAG #(.pt(pt)) ic_tag_inst
(
EL2_IC_TAG #(
.pt(pt)
) ic_tag_inst (
.*,
.ic_wr_en (ic_wr_en[pt.ICACHE_NUM_WAYS-1:0]),
.ic_debug_addr(ic_debug_addr[pt.ICACHE_INDEX_HI:3]),
.ic_rw_addr (ic_rw_addr[31:3])
);
EL2_IC_DATA #(.pt(pt)) ic_data_inst
(
EL2_IC_DATA #(
.pt(pt)
) ic_data_inst (
.*,
.ic_wr_en (ic_wr_en[pt.ICACHE_NUM_WAYS-1:0]),
.ic_debug_addr(ic_debug_addr[pt.ICACHE_INDEX_HI:3]),
@ -86,8 +87,7 @@ module EL2_IC_DATA
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk,
input logic active_clk,
input logic rst_l,
@ -232,10 +232,23 @@ import el2_pkg::*;
assign ic_rw_addr_bank_q[1] = ic_rw_addr_q[pt.ICACHE_INDEX_HI:pt.ICACHE_DATA_INDEX_LO];
rvdffie #(.WIDTH(int'(pt.ICACHE_TAG_INDEX_LO+pt.ICACHE_BANKS_WAY+pt.ICACHE_NUM_WAYS)),.OVERRIDE(1)) miscff
(.*,
.din({ ic_b_rden[pt.ICACHE_BANKS_WAY-1:0], ic_rw_addr_q[pt.ICACHE_TAG_INDEX_LO-1:1], ic_debug_rd_way_en[pt.ICACHE_NUM_WAYS-1:0], ic_debug_rd_en}),
.dout({ic_b_rden_ff[pt.ICACHE_BANKS_WAY-1:0],ic_rw_addr_ff[pt.ICACHE_TAG_INDEX_LO-1:1],ic_debug_rd_way_en_ff[pt.ICACHE_NUM_WAYS-1:0],ic_debug_rd_en_ff})
rvdffie #(
.WIDTH(int'(pt.ICACHE_TAG_INDEX_LO + pt.ICACHE_BANKS_WAY + pt.ICACHE_NUM_WAYS)),
.OVERRIDE(1)
) miscff (
.*,
.din({
ic_b_rden[pt.ICACHE_BANKS_WAY-1:0],
ic_rw_addr_q[pt.ICACHE_TAG_INDEX_LO-1:1],
ic_debug_rd_way_en[pt.ICACHE_NUM_WAYS-1:0],
ic_debug_rd_en
}),
.dout({
ic_b_rden_ff[pt.ICACHE_BANKS_WAY-1:0],
ic_rw_addr_ff[pt.ICACHE_TAG_INDEX_LO-1:1],
ic_debug_rd_way_en_ff[pt.ICACHE_NUM_WAYS-1:0],
ic_debug_rd_en_ff
})
);
if (pt.ICACHE_WAYPACK == 0) begin : PACKED_0
@ -327,26 +340,19 @@ if (pt.ICACHE_BYPASS_ENABLE == 1) begin \
if ($clog2(pt.ICACHE_DATA_DEPTH) == 13) begin : size_8192
`EL2_IC_DATA_SRAM(8192, 71)
end
else if ($clog2(pt.ICACHE_DATA_DEPTH) == 12 ) begin : size_4096
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 12) begin : size_4096
`EL2_IC_DATA_SRAM(4096, 71)
end
else if ($clog2(pt.ICACHE_DATA_DEPTH) == 11 ) begin : size_2048
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 11) begin : size_2048
`EL2_IC_DATA_SRAM(2048, 71)
end
else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 10 ) begin : size_1024
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 10) begin : size_1024
`EL2_IC_DATA_SRAM(1024, 71)
end
else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 9 ) begin : size_512
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 9) begin : size_512
`EL2_IC_DATA_SRAM(512, 71)
end
else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 8 ) begin : size_256
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 8) begin : size_256
`EL2_IC_DATA_SRAM(256, 71)
end
else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 7 ) begin : size_128
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 7) begin : size_128
`EL2_IC_DATA_SRAM(128, 71)
end
else begin : size_64
end else begin : size_64
`EL2_IC_DATA_SRAM(64, 71)
end
end // if (pt.ICACHE_ECC)
@ -356,26 +362,19 @@ if (pt.ICACHE_BYPASS_ENABLE == 1) begin \
logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] [pt.ICACHE_NUM_BYPASS-1:0] [68-1:0] wb_dout_hold_up;
if ($clog2(pt.ICACHE_DATA_DEPTH) == 13) begin : size_8192
`EL2_IC_DATA_SRAM(8192, 68)
end
else if ($clog2(pt.ICACHE_DATA_DEPTH) == 12 ) begin : size_4096
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 12) begin : size_4096
`EL2_IC_DATA_SRAM(4096, 68)
end
else if ($clog2(pt.ICACHE_DATA_DEPTH) == 11 ) begin : size_2048
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 11) begin : size_2048
`EL2_IC_DATA_SRAM(2048, 68)
end
else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 10 ) begin : size_1024
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 10) begin : size_1024
`EL2_IC_DATA_SRAM(1024, 68)
end
else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 9 ) begin : size_512
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 9) begin : size_512
`EL2_IC_DATA_SRAM(512, 68)
end
else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 8 ) begin : size_256
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 8) begin : size_256
`EL2_IC_DATA_SRAM(256, 68)
end
else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 7 ) begin : size_128
end else if ($clog2(pt.ICACHE_DATA_DEPTH) == 7) begin : size_128
`EL2_IC_DATA_SRAM(128, 68)
end
else begin : size_64
end else begin : size_64
`EL2_IC_DATA_SRAM(64, 68)
end
end // else: !if(pt.ICACHE_ECC)
@ -490,7 +489,8 @@ if (pt.ICACHE_BYPASS_ENABLE == 1) begin \
// generate IC DATA PACKED SRAMS for 2/4 ways
for (genvar k = 0; k < pt.ICACHE_BANKS_WAY; k++) begin : BANKS_WAY // 16B subbank
if (pt.ICACHE_ECC) begin : ECC1
logic [pt.ICACHE_BANKS_WAY-1:0] [(71*pt.ICACHE_NUM_WAYS)-1:0] wb_packeddout, ic_b_sb_bit_en_vec, wb_packeddout_pre; // data and its bit enables
logic [pt.ICACHE_BANKS_WAY-1:0][(71*pt.ICACHE_NUM_WAYS)-1:0]
wb_packeddout, ic_b_sb_bit_en_vec, wb_packeddout_pre; // data and its bit enables
logic [pt.ICACHE_BANKS_WAY-1:0] [pt.ICACHE_NUM_BYPASS-1:0] [(71*pt.ICACHE_NUM_WAYS)-1:0] wb_packeddout_hold;
@ -580,7 +580,8 @@ if (pt.ICACHE_BYPASS_ENABLE == 1) begin \
else begin : ECC0
logic [pt.ICACHE_BANKS_WAY-1:0] [(68*pt.ICACHE_NUM_WAYS)-1:0] wb_packeddout, ic_b_sb_bit_en_vec, wb_packeddout_pre; // data and its bit enables
logic [pt.ICACHE_BANKS_WAY-1:0][(68*pt.ICACHE_NUM_WAYS)-1:0]
wb_packeddout, ic_b_sb_bit_en_vec, wb_packeddout_pre; // data and its bit enables
logic [pt.ICACHE_BANKS_WAY-1:0] [pt.ICACHE_NUM_BYPASS-1:0] [(68*pt.ICACHE_NUM_WAYS)-1:0] wb_packeddout_hold;
@ -717,7 +718,8 @@ if (pt.ICACHE_BYPASS_ENABLE == 1) begin \
.en (bank_check_en[i]),
.din (wb_dout_ecc_bank[i][63 : 0]), // [134:71], [63:0]
.ecc_in (wb_dout_ecc_bank[i][70 : 64]), // [141:135] [70:64]
.ecc_error (ic_eccerr[i]));
.ecc_error(ic_eccerr[i])
);
// or the sb and db error detects into 1 signal called aligndataperr[i] where i corresponds to 2B position
assign ic_parerr[i] = '0;
@ -798,8 +800,7 @@ module EL2_IC_TAG
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk,
input logic active_clk,
input logic rst_l,
@ -855,12 +856,16 @@ import el2_pkg::*;
assign ic_tag_wren [pt.ICACHE_NUM_WAYS-1:0] = ic_wr_en[pt.ICACHE_NUM_WAYS-1:0] & {pt.ICACHE_NUM_WAYS{(ic_rw_addr[pt.ICACHE_BEAT_ADDR_HI:4] == {pt.ICACHE_BEAT_BITS-1{1'b1}})}} ;
assign ic_tag_clken[pt.ICACHE_NUM_WAYS-1:0] = {pt.ICACHE_NUM_WAYS{ic_rd_en | clk_override}} | ic_wr_en[pt.ICACHE_NUM_WAYS-1:0] | ic_debug_wr_way_en[pt.ICACHE_NUM_WAYS-1:0] | ic_debug_rd_way_en[pt.ICACHE_NUM_WAYS-1:0];
rvdff #(1) rd_en_ff (.*, .clk(active_clk),
rvdff #(1) rd_en_ff (
.*,
.clk (active_clk),
.din (ic_rd_en),
.dout(ic_rd_en_ff)) ;
.dout(ic_rd_en_ff)
);
rvdffie #(32-pt.ICACHE_TAG_LO) adr_ff (.*,
rvdffie #(32 - pt.ICACHE_TAG_LO) adr_ff (
.*,
.din ({ic_rw_addr[31:pt.ICACHE_TAG_LO]}),
.dout({ic_rw_addr_ff[31:pt.ICACHE_TAG_LO]})
);
@ -880,16 +885,17 @@ if (pt.ICACHE_TAG_LO == 11) begin: SMALLEST
if (pt.ICACHE_ECC) begin : ECC1_W
rvecc_encode tag_ecc_encode (
.din ({{pt.ICACHE_TAG_LO{1'b0}}, ic_rw_addr[31:pt.ICACHE_TAG_LO]}),
.ecc_out({ ic_tag_ecc[6:0]}));
.ecc_out({ic_tag_ecc[6:0]})
);
assign ic_tag_wr_data[25:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[68:64], ic_debug_wr_data[31:11]} :
{ic_tag_ecc[4:0], ic_rw_addr[31:pt.ICACHE_TAG_LO]} ;
end
else begin : ECC0_W
rveven_paritygen #(32-pt.ICACHE_TAG_LO) pargen (.data_in (ic_rw_addr[31:pt.ICACHE_TAG_LO]),
.parity_out(ic_tag_parity));
end else begin : ECC0_W
rveven_paritygen #(32 - pt.ICACHE_TAG_LO) pargen (
.data_in (ic_rw_addr[31:pt.ICACHE_TAG_LO]),
.parity_out(ic_tag_parity)
);
assign ic_tag_wr_data[21:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[64], ic_debug_wr_data[31:11]} :
@ -903,17 +909,19 @@ else begin: OTHERS
if (pt.ICACHE_ECC) begin : ECC1_W
rvecc_encode tag_ecc_encode (
.din ({{pt.ICACHE_TAG_LO{1'b0}}, ic_rw_addr[31:pt.ICACHE_TAG_LO]}),
.ecc_out({ ic_tag_ecc[6:0]}));
.ecc_out({ic_tag_ecc[6:0]})
);
assign ic_tag_wr_data[25:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[68:64],ic_debug_wr_data[31:11]} :
{ic_tag_ecc[4:0], {PAD_BITS{1'b0}},ic_rw_addr[31:pt.ICACHE_TAG_LO]} ;
end
else begin :ECC0_W
end else begin : ECC0_W
logic ic_tag_parity;
rveven_paritygen #(32-pt.ICACHE_TAG_LO) pargen (.data_in (ic_rw_addr[31:pt.ICACHE_TAG_LO]),
.parity_out(ic_tag_parity));
rveven_paritygen #(32 - pt.ICACHE_TAG_LO) pargen (
.data_in (ic_rw_addr[31:pt.ICACHE_TAG_LO]),
.parity_out(ic_tag_parity)
);
assign ic_tag_wr_data[21:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
{ic_debug_wr_data[64], ic_debug_wr_data[31:11]} :
{ic_tag_parity, {PAD_BITS{1'b0}},ic_rw_addr[31:pt.ICACHE_TAG_LO]} ;
@ -926,9 +934,12 @@ end // block: OTHERS
ic_debug_addr[pt.ICACHE_INDEX_HI: pt.ICACHE_TAG_INDEX_LO] :
ic_rw_addr[pt.ICACHE_INDEX_HI: pt.ICACHE_TAG_INDEX_LO] ;
rvdff #(pt.ICACHE_NUM_WAYS) tag_rd_wy_ff (.*, .clk(active_clk),
rvdff #(pt.ICACHE_NUM_WAYS) tag_rd_wy_ff (
.*,
.clk (active_clk),
.din ({ic_debug_rd_way_en[pt.ICACHE_NUM_WAYS-1:0]}),
.dout({ic_debug_rd_way_en_ff[pt.ICACHE_NUM_WAYS-1:0]}));
.dout({ic_debug_rd_way_en_ff[pt.ICACHE_NUM_WAYS-1:0]})
);
if (pt.ICACHE_WAYPACK == 0) begin : PACKED_0
@ -1086,11 +1097,11 @@ end // block: OTHERS
.dout(ic_tag_corrected_data_unc[i][31:0]),
.ecc_out(ic_tag_corrected_ecc_unc[i][6:0]),
.single_ecc_error(ic_tag_single_ecc_error[i]),
.double_ecc_error(ic_tag_double_ecc_error[i]));
.double_ecc_error(ic_tag_double_ecc_error[i])
);
assign ic_tag_way_perr[i] = ic_tag_single_ecc_error[i] | ic_tag_double_ecc_error[i];
end
else begin : ECC0
end else begin : ECC0
logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_TAG_NUM_BYPASS-1:0][21 : 0] wb_dout_hold;
assign ic_tag_data_raw_pre[i][25:22] = '0;
@ -1122,9 +1133,11 @@ end // block: OTHERS
assign w_tout[i][31:pt.ICACHE_TAG_LO] = ic_tag_data_raw[i][31-pt.ICACHE_TAG_LO:0];
assign w_tout[i][32] = ic_tag_data_raw[i][21];
rveven_paritycheck #(32-pt.ICACHE_TAG_LO) parcheck(.data_in (w_tout[i][31:pt.ICACHE_TAG_LO]),
rveven_paritycheck #(32 - pt.ICACHE_TAG_LO) parcheck (
.data_in (w_tout[i][31:pt.ICACHE_TAG_LO]),
.parity_in (w_tout[i][32]),
.parity_err(ic_tag_way_perr[i]));
.parity_err(ic_tag_way_perr[i])
);
end // else: !if(pt.ICACHE_ECC)
end // block: WAYS
@ -1248,7 +1261,10 @@ end // block: OTHERS
end
if (pt.ICACHE_ECC) begin : ECC1
logic [(26*pt.ICACHE_NUM_WAYS)-1 :0] ic_tag_data_raw_packed, ic_tag_wren_biten_vec, ic_tag_data_raw_packed_pre; // data and its bit enables
logic [(26*pt.ICACHE_NUM_WAYS)-1 : 0]
ic_tag_data_raw_packed,
ic_tag_wren_biten_vec,
ic_tag_data_raw_packed_pre; // data and its bit enables
logic [pt.ICACHE_TAG_NUM_BYPASS-1:0][(26*pt.ICACHE_NUM_WAYS)-1 :0] wb_packeddout_hold;
for (genvar i = 0; i < pt.ICACHE_NUM_WAYS; i++) begin : BITEN
assign ic_tag_wren_biten_vec[(26*i)+25:26*i] = {26{ic_tag_wren_q[i]}};
@ -1338,7 +1354,8 @@ end // block: OTHERS
.dout(ic_tag_corrected_data_unc[i][31:0]),
.ecc_out(ic_tag_corrected_ecc_unc[i][6:0]),
.single_ecc_error(ic_tag_single_ecc_error[i]),
.double_ecc_error(ic_tag_double_ecc_error[i]));
.double_ecc_error(ic_tag_double_ecc_error[i])
);
assign ic_tag_way_perr[i] = ic_tag_single_ecc_error[i] | ic_tag_double_ecc_error[i];
end // for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++)
@ -1347,7 +1364,10 @@ end // block: OTHERS
else begin : ECC0
logic [(22*pt.ICACHE_NUM_WAYS)-1 :0] ic_tag_data_raw_packed, ic_tag_wren_biten_vec, ic_tag_data_raw_packed_pre; // data and its bit enables
logic [(22*pt.ICACHE_NUM_WAYS)-1 : 0]
ic_tag_data_raw_packed,
ic_tag_wren_biten_vec,
ic_tag_data_raw_packed_pre; // data and its bit enables
logic [pt.ICACHE_TAG_NUM_BYPASS-1:0][(22*pt.ICACHE_NUM_WAYS)-1 :0] wb_packeddout_hold;
for (genvar i = 0; i < pt.ICACHE_NUM_WAYS; i++) begin : BITEN
assign ic_tag_wren_biten_vec[(22*i)+21:22*i] = {22{ic_tag_wren_q[i]}};
@ -1432,9 +1452,11 @@ end // block: OTHERS
assign w_tout[i][36:33] = '0;
rveven_paritycheck #(32-pt.ICACHE_TAG_LO) parcheck(.data_in (w_tout[i][31:pt.ICACHE_TAG_LO]),
rveven_paritycheck #(32 - pt.ICACHE_TAG_LO) parcheck (
.data_in (w_tout[i][31:pt.ICACHE_TAG_LO]),
.parity_in (w_tout[i][32]),
.parity_err(ic_tag_way_perr[i]));
.parity_err(ic_tag_way_perr[i])
);
end

View File

@ -110,7 +110,10 @@ import el2_pkg::*;
iccm_rw_addr[pt.ICCM_BITS-1 : pt.ICCM_BANK_INDEX_LO]);
`ifdef VERILATOR
el2_ram #(.depth(1<<pt.ICCM_INDEX_BITS), .width(39)) iccm_bank (
el2_ram #(
.depth(1 << pt.ICCM_INDEX_BITS),
.width(39)
) iccm_bank (
// Primary ports
.ME(iccm_clken[i]),
.CLK(clk),
@ -374,15 +377,19 @@ import el2_pkg::*;
assign sel_red0[i] = (redundant_valid[0] & (((iccm_rw_addr[pt.ICCM_BITS-1:2] == redundant_address[0][pt.ICCM_BITS-1:2]) & (iccm_rw_addr[3:2] == i)) |
((addr_bank_inc[pt.ICCM_BITS-1:2]== redundant_address[0][pt.ICCM_BITS-1:2]) & (addr_bank_inc[3:2] == i))));
rvdff #(1) selred0 (.*,
rvdff #(1) selred0 (
.*,
.clk (active_clk),
.din (sel_red0[i]),
.dout(sel_red0_q[i]));
.dout(sel_red0_q[i])
);
rvdff #(1) selred1 (.*,
rvdff #(1) selred1 (
.*,
.clk (active_clk),
.din (sel_red1[i]),
.dout(sel_red1_q[i]));
.dout(sel_red1_q[i])
);
// muxing out the memory data with the redundant data if the address matches
@ -399,35 +406,45 @@ import el2_pkg::*;
assign redundant_lru_en = iccm_buf_correct_ecc | (((|sel_red0[pt.ICCM_NUM_BANKS-1:0]) | (|sel_red1[pt.ICCM_NUM_BANKS-1:0])) & iccm_rden & iccm_correction_state);
assign redundant_lru_in = iccm_buf_correct_ecc ? ~redundant_lru : (|sel_red0[pt.ICCM_NUM_BANKS-1:0]) ? 1'b1 : 1'b0;
rvdffs #() red_lru (.*, // LRU flop for the redundant replacements
rvdffs #() red_lru (
.*, // LRU flop for the redundant replacements
.clk (active_clk),
.en (redundant_lru_en),
.din (redundant_lru_in),
.dout(redundant_lru));
.dout(redundant_lru)
);
rvdffs #(pt.ICCM_BITS-2) r0_address (.*, // Redundant Row 0 address
rvdffs #(pt.ICCM_BITS - 2) r0_address (
.*, // Redundant Row 0 address
.clk (active_clk),
.en (r0_addr_en),
.din (iccm_rw_addr[pt.ICCM_BITS-1:2]),
.dout(redundant_address[0][pt.ICCM_BITS-1:2]));
.dout(redundant_address[0][pt.ICCM_BITS-1:2])
);
rvdffs #(pt.ICCM_BITS-2) r1_address (.*, // Redundant Row 0 address
rvdffs #(pt.ICCM_BITS - 2) r1_address (
.*, // Redundant Row 0 address
.clk (active_clk),
.en (r1_addr_en),
.din (iccm_rw_addr[pt.ICCM_BITS-1:2]),
.dout(redundant_address[1][pt.ICCM_BITS-1:2]));
.dout(redundant_address[1][pt.ICCM_BITS-1:2])
);
rvdffs #(1) r0_valid (.*,
rvdffs #(1) r0_valid (
.*,
.clk (active_clk), // Redundant Row 0 Valid
.en (r0_addr_en),
.din (1'b1),
.dout(redundant_valid[0]));
.dout(redundant_valid[0])
);
rvdffs #(1) r1_valid (.*, // Redundant Row 1 Valid
rvdffs #(1) r1_valid (
.*, // Redundant Row 1 Valid
.clk (active_clk),
.en (r1_addr_en),
.din (1'b1),
.dout(redundant_valid[1]));
.dout(redundant_valid[1])
);
@ -440,30 +457,52 @@ import el2_pkg::*;
assign redundant_data0_in[38:0] = (((iccm_rw_addr[2] == redundant_address[0][2]) & iccm_rw_addr[2]) | (redundant_address[0][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
rvdffs #(39) r0_data (.*, // Redundant Row 1 data
rvdffs #(39) r0_data (
.*, // Redundant Row 1 data
.clk (active_clk),
.en (redundant_data0_en),
.din (redundant_data0_in[38:0]),
.dout(redundant_data[0][38:0]));
.dout(redundant_data[0][38:0])
);
assign redundant_data1_en = ((iccm_rw_addr[pt.ICCM_BITS-1:3] == redundant_address[1][pt.ICCM_BITS-1:3]) & ((iccm_rw_addr[2] == redundant_address[1][2]) | (iccm_wr_size[1:0] == 2'b11)) & redundant_valid[1] & iccm_wren) |
(redundant_lru & iccm_buf_correct_ecc);
assign redundant_data1_in[38:0] = (((iccm_rw_addr[2] == redundant_address[1][2]) & iccm_rw_addr[2]) | (redundant_address[1][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
rvdffs #(39) r1_data (.*, // Redundant Row 1 data
rvdffs #(39) r1_data (
.*, // Redundant Row 1 data
.clk (active_clk),
.en (redundant_data1_en),
.din (redundant_data1_in[38:0]),
.dout(redundant_data[1][38:0]));
.dout(redundant_data[1][38:0])
);
rvdffs #(pt.ICCM_BANK_HI) rd_addr_lo_ff (.*, .clk(active_clk), .din(iccm_rw_addr [pt.ICCM_BANK_HI:1]), .dout(iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:1]), .en(1'b1)); // bit 0 of address is always 0
rvdffs #(pt.ICCM_BANK_BITS) rd_addr_hi_ff (.*, .clk(active_clk), .din(addr_bank_inc[pt.ICCM_BANK_HI:2]), .dout(iccm_rd_addr_hi_q[pt.ICCM_BANK_HI:2]), .en(1'b1));
rvdffs #(pt.ICCM_BANK_HI) rd_addr_lo_ff (
.*,
.clk (active_clk),
.din (iccm_rw_addr[pt.ICCM_BANK_HI:1]),
.dout(iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:1]),
.en (1'b1)
); // bit 0 of address is always 0
rvdffs #(pt.ICCM_BANK_BITS) rd_addr_hi_ff (
.*,
.clk (active_clk),
.din (addr_bank_inc[pt.ICCM_BANK_HI:2]),
.dout(iccm_rd_addr_hi_q[pt.ICCM_BANK_HI:2]),
.en (1'b1)
);
assign iccm_rd_data_pre[63:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][31:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:2]][31:0]};
assign iccm_rd_data_pre[63:0] = {
iccm_bank_dout_fn[iccm_rd_addr_hi_q][31:0],
iccm_bank_dout_fn[iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:2]][31:0]
};
assign iccm_data[63:0] = 64'({16'b0, (iccm_rd_data_pre[63:0] >> (16 * iccm_rd_addr_lo_q[1]))});
assign iccm_rd_data[63:0] = {iccm_data[63:0]};
assign iccm_rd_data_ecc[77:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][38:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:2]][38:0]};
assign iccm_rd_data_ecc[77:0] = {
iccm_bank_dout_fn[iccm_rd_addr_hi_q][38:0],
iccm_bank_dout_fn[iccm_rd_addr_lo_q[pt.ICCM_BANK_HI:2]][38:0]
};
endmodule // el2_ifu_iccm_mem

View File

@ -24,8 +24,7 @@ module el2_ifu_ifc_ctl
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in.
@ -84,10 +83,12 @@ import el2_pkg::*;
logic fetch_addr_next_1;
// FSM assignment
typedef enum logic [1:0] { IDLE = 2'b00 ,
typedef enum logic [1:0] {
IDLE = 2'b00,
FETCH = 2'b01,
STALL = 2'b10,
WFM = 2'b11 } state_t ;
WFM = 2'b11
} state_t;
state_t state;
state_t next_state;
@ -198,9 +199,19 @@ end
assign idle = state == IDLE;
assign wfm = state == WFM;
rvdffie #(10) fbwrite_ff (.*, .clk(free_l2clk),
.din( {dma_iccm_stall_any, miss_f, ifc_fetch_req_bf, next_state[1:0], fb_full_f_ns, fb_write_ns[3:0]}),
.dout({dma_iccm_stall_any_f, miss_a, ifc_fetch_req_f, state[1:0], fb_full_f, fb_write_f[3:0]}));
rvdffie #(10) fbwrite_ff (
.*,
.clk(free_l2clk),
.din({
dma_iccm_stall_any,
miss_f,
ifc_fetch_req_bf,
next_state[1:0],
fb_full_f_ns,
fb_write_ns[3:0]
}),
.dout({dma_iccm_stall_any_f, miss_a, ifc_fetch_req_f, state[1:0], fb_full_f, fb_write_f[3:0]})
);
assign ifu_pmu_fetch_stall = wfm |
(ifc_fetch_req_bf_raw &
@ -211,14 +222,21 @@ end
assign ifc_fetch_addr_bf[31:1] = fetch_addr_bf[31:1];
rvdffpcie #(31) faddrf1_ff (.*, .en(fetch_bf_en), .din(fetch_addr_bf[31:1]), .dout(ifc_fetch_addr_f[31:1]));
rvdffpcie #(31) faddrf1_ff (
.*,
.en (fetch_bf_en),
.din (fetch_addr_bf[31:1]),
.dout(ifc_fetch_addr_f[31:1])
);
if (pt.ICCM_ENABLE) begin
logic iccm_acc_in_region_bf;
logic iccm_acc_in_range_bf;
rvrangecheck #( .CCM_SADR (pt.ICCM_SADR),
.CCM_SIZE (pt.ICCM_SIZE) ) iccm_rangecheck (
rvrangecheck #(
.CCM_SADR(pt.ICCM_SADR),
.CCM_SIZE(pt.ICCM_SIZE)
) iccm_rangecheck (
.addr ({ifc_fetch_addr_bf[31:1], 1'b0}),
.in_range (iccm_acc_in_range_bf),
.in_region(iccm_acc_in_region_bf)
@ -233,14 +251,15 @@ end
dma_iccm_stall_any_f;
assign ifc_region_acc_fault_bf = ~iccm_acc_in_range_bf & iccm_acc_in_region_bf;
end
else begin
end else begin
assign ifc_iccm_access_bf = 1'b0;
assign ifc_dma_access_ok = 1'b0;
assign ifc_region_acc_fault_bf = 1'b0;
end
assign ifc_fetch_uncacheable_bf = ~dec_tlu_mrac_ff[{ifc_fetch_addr_bf[31:28] , 1'b0 }] ; // bit 0 of each region description is the cacheable bit
assign ifc_fetch_uncacheable_bf = ~dec_tlu_mrac_ff[{
ifc_fetch_addr_bf[31:28], 1'b0
}]; // bit 0 of each region description is the cacheable bit
endmodule // el2_ifu_ifc_ctl

View File

@ -25,8 +25,7 @@ module el2_ifu_mem_ctl
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in.
@ -422,10 +421,24 @@ import el2_pkg::*;
logic dma_sb_err_state, dma_sb_err_state_ff;
logic two_byte_instr;
typedef enum logic [2:0] {IDLE=3'b000, CRIT_BYP_OK=3'b001, HIT_U_MISS=3'b010, MISS_WAIT=3'b011,CRIT_WRD_RDY=3'b100,SCND_MISS=3'b101,STREAM=3'b110 , STALL_SCND_MISS=3'b111} miss_state_t;
typedef enum logic [2:0] {
IDLE = 3'b000,
CRIT_BYP_OK = 3'b001,
HIT_U_MISS = 3'b010,
MISS_WAIT = 3'b011,
CRIT_WRD_RDY = 3'b100,
SCND_MISS = 3'b101,
STREAM = 3'b110,
STALL_SCND_MISS = 3'b111
} miss_state_t;
miss_state_t miss_state, miss_nxtstate;
typedef enum logic [1:0] {ERR_STOP_IDLE=2'b00, ERR_FETCH1=2'b01 , ERR_FETCH2=2'b10 , ERR_STOP_FETCH=2'b11} err_stop_state_t;
typedef enum logic [1:0] {
ERR_STOP_IDLE = 2'b00,
ERR_FETCH1 = 2'b01,
ERR_FETCH2 = 2'b10,
ERR_STOP_FETCH = 2'b11
} err_stop_state_t;
err_stop_state_t err_stop_state, err_stop_nxtstate;
logic err_stop_state_en;
logic err_stop_fetch;
@ -445,8 +458,16 @@ import el2_pkg::*;
assign debug_c1_clken = ic_debug_rd_en | ic_debug_wr_en;
// C1 - 1 clock pulse for data
rvclkhdr fetch_bf_f_c1_cgc ( .en(fetch_bf_f_c1_clken), .l1clk(fetch_bf_f_c1_clk), .* );
rvclkhdr debug_c1_cgc ( .en(debug_c1_clken), .l1clk(debug_c1_clk), .* );
rvclkhdr fetch_bf_f_c1_cgc (
.en(fetch_bf_f_c1_clken),
.l1clk(fetch_bf_f_c1_clk),
.*
);
rvclkhdr debug_c1_cgc (
.en(debug_c1_clken),
.l1clk(debug_c1_clk),
.*
);
// ------ end clock gating section ------------------------
@ -456,7 +477,13 @@ import el2_pkg::*;
assign ifu_async_error_start = iccm_rd_ecc_single_err | ic_error_start;
typedef enum logic [2:0] {ERR_IDLE=3'b000, IC_WFF=3'b001 , ECC_WFF=3'b010 , ECC_CORR=3'b011, DMA_SB_ERR=3'b100} perr_state_t;
typedef enum logic [2:0] {
ERR_IDLE = 3'b000,
IC_WFF = 3'b001,
ECC_WFF = 3'b010,
ECC_CORR = 3'b011,
DMA_SB_ERR = 3'b100
} perr_state_t;
perr_state_t perr_state, perr_nxtstate;
@ -528,7 +555,15 @@ import el2_pkg::*;
end
endcase
end
rvdffs #(($bits(miss_state_t))) miss_state_ff (.clk(active_clk), .din(miss_nxtstate), .dout({miss_state}), .en(miss_state_en), .*);
rvdffs #(($bits(
miss_state_t
))) miss_state_ff (
.clk (active_clk),
.din (miss_nxtstate),
.dout({miss_state}),
.en (miss_state_en),
.*
);
logic sel_hold_imb;
@ -557,10 +592,36 @@ import el2_pkg::*;
assign uncacheable_miss_scnd_in = sel_hold_imb_scnd ? uncacheable_miss_scnd_ff : ifc_fetch_uncacheable_bf ;
rvdff_fpga #(1) unc_miss_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din (uncacheable_miss_scnd_in), .dout(uncacheable_miss_scnd_ff));
rvdffpcie #(31) imb_f_scnd_ff (.*, .en(fetch_bf_f_c1_clken), .din ({imb_scnd_in[31:1]}), .dout({imb_scnd_ff[31:1]}));
rvdff_fpga #(pt.ICACHE_STATUS_BITS) mb_rep_wayf2_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({way_status_mb_scnd_in[pt.ICACHE_STATUS_BITS-1:0]}), .dout({way_status_mb_scnd_ff[pt.ICACHE_STATUS_BITS-1:0]}));
rvdff_fpga #(pt.ICACHE_NUM_WAYS) mb_tagv_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({tagv_mb_scnd_in[pt.ICACHE_NUM_WAYS-1:0]}), .dout({tagv_mb_scnd_ff[pt.ICACHE_NUM_WAYS-1:0]}));
rvdff_fpga #(1) unc_miss_scnd_ff (
.*,
.clk(fetch_bf_f_c1_clk),
.clken(fetch_bf_f_c1_clken),
.rawclk(clk),
.din(uncacheable_miss_scnd_in),
.dout(uncacheable_miss_scnd_ff)
);
rvdffpcie #(31) imb_f_scnd_ff (
.*,
.en (fetch_bf_f_c1_clken),
.din ({imb_scnd_in[31:1]}),
.dout({imb_scnd_ff[31:1]})
);
rvdff_fpga #(pt.ICACHE_STATUS_BITS) mb_rep_wayf2_scnd_ff (
.*,
.clk(fetch_bf_f_c1_clk),
.clken(fetch_bf_f_c1_clken),
.rawclk(clk),
.din({way_status_mb_scnd_in[pt.ICACHE_STATUS_BITS-1:0]}),
.dout({way_status_mb_scnd_ff[pt.ICACHE_STATUS_BITS-1:0]})
);
rvdff_fpga #(pt.ICACHE_NUM_WAYS) mb_tagv_scnd_ff (
.*,
.clk(fetch_bf_f_c1_clk),
.clken(fetch_bf_f_c1_clken),
.rawclk(clk),
.din({tagv_mb_scnd_in[pt.ICACHE_NUM_WAYS-1:0]}),
.dout({tagv_mb_scnd_ff[pt.ICACHE_NUM_WAYS-1:0]})
);
@ -602,37 +663,99 @@ import el2_pkg::*;
rvdffpcie #(31) ifu_fetch_addr_f_ff (.*, .en(fetch_bf_f_c1_clken), .din ({ifc_fetch_addr_bf[31:1]}), .dout({ifu_fetch_addr_int_f[31:1]}));
rvdffpcie #(31) ifu_fetch_addr_f_ff (
.*,
.en (fetch_bf_f_c1_clken),
.din ({ifc_fetch_addr_bf[31:1]}),
.dout({ifu_fetch_addr_int_f[31:1]})
);
assign vaddr_f[pt.ICACHE_BEAT_ADDR_HI:1] = ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:1];
rvdffpcie #(31) imb_f_ff (.*, .en(fetch_bf_f_c1_clken), .din (imb_in[31:1]), .dout(imb_ff[31:1]));
rvdff_fpga #(1) unc_miss_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ( uncacheable_miss_in), .dout( uncacheable_miss_ff));
rvdffpcie #(31) imb_f_ff (
.*,
.en (fetch_bf_f_c1_clken),
.din (imb_in[31:1]),
.dout(imb_ff[31:1])
);
rvdff_fpga #(1) unc_miss_ff (
.*,
.clk(fetch_bf_f_c1_clk),
.clken(fetch_bf_f_c1_clken),
.rawclk(clk),
.din(uncacheable_miss_in),
.dout(uncacheable_miss_ff)
);
assign miss_addr_in[31:pt.ICACHE_BEAT_ADDR_HI+1] = (~miss_pending ) ? imb_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] :
( scnd_miss_req_q ) ? imb_scnd_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] : miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1] ;
rvdfflie #(.WIDTH(31-pt.ICACHE_BEAT_ADDR_HI),.LEFT(31-pt.ICACHE_BEAT_ADDR_HI-8)) miss_f_ff (.*, .en(bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt), .din ({miss_addr_in[31:pt.ICACHE_BEAT_ADDR_HI+1]}), .dout({miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1]}));
rvdfflie #(
.WIDTH(31 - pt.ICACHE_BEAT_ADDR_HI),
.LEFT (31 - pt.ICACHE_BEAT_ADDR_HI - 8)
) miss_f_ff (
.*,
.en (bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt),
.din ({miss_addr_in[31:pt.ICACHE_BEAT_ADDR_HI+1]}),
.dout({miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1]})
);
rvdff_fpga #(pt.ICACHE_STATUS_BITS) mb_rep_wayf2_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({way_status_mb_in[pt.ICACHE_STATUS_BITS-1:0]}), .dout({way_status_mb_ff[pt.ICACHE_STATUS_BITS-1:0]}));
rvdff_fpga #(pt.ICACHE_NUM_WAYS) mb_tagv_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({tagv_mb_in[pt.ICACHE_NUM_WAYS-1:0]}), .dout({tagv_mb_ff[pt.ICACHE_NUM_WAYS-1:0]}));
rvdff_fpga #(pt.ICACHE_STATUS_BITS) mb_rep_wayf2_ff (
.*,
.clk(fetch_bf_f_c1_clk),
.clken(fetch_bf_f_c1_clken),
.rawclk(clk),
.din({way_status_mb_in[pt.ICACHE_STATUS_BITS-1:0]}),
.dout({way_status_mb_ff[pt.ICACHE_STATUS_BITS-1:0]})
);
rvdff_fpga #(pt.ICACHE_NUM_WAYS) mb_tagv_ff (
.*,
.clk(fetch_bf_f_c1_clk),
.clken(fetch_bf_f_c1_clken),
.rawclk(clk),
.din({tagv_mb_in[pt.ICACHE_NUM_WAYS-1:0]}),
.dout({tagv_mb_ff[pt.ICACHE_NUM_WAYS-1:0]})
);
assign ifc_fetch_req_qual_bf = ifc_fetch_req_bf & ~((miss_state == CRIT_WRD_RDY) & flush_final_f) & ~stream_miss_f ;// & ~exu_flush_final ;
assign ifc_fetch_req_f = ifc_fetch_req_f_raw & ~exu_flush_final;
rvdff_fpga #(1) ifu_iccm_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din(ifc_iccm_access_bf), .dout(ifc_iccm_access_f));
rvdff_fpga #(1) ifu_iccm_reg_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din(ifc_region_acc_fault_final_bf), .dout(ifc_region_acc_fault_final_f));
rvdff_fpga #(1) rgn_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din(ifc_region_acc_fault_bf), .dout(ifc_region_acc_fault_f));
rvdff_fpga #(1) ifu_iccm_acc_ff (
.*,
.clk(fetch_bf_f_c1_clk),
.clken(fetch_bf_f_c1_clken),
.rawclk(clk),
.din(ifc_iccm_access_bf),
.dout(ifc_iccm_access_f)
);
rvdff_fpga #(1) ifu_iccm_reg_acc_ff (
.*,
.clk(fetch_bf_f_c1_clk),
.clken(fetch_bf_f_c1_clken),
.rawclk(clk),
.din(ifc_region_acc_fault_final_bf),
.dout(ifc_region_acc_fault_final_f)
);
rvdff_fpga #(1) rgn_acc_ff (
.*,
.clk(fetch_bf_f_c1_clk),
.clken(fetch_bf_f_c1_clken),
.rawclk(clk),
.din(ifc_region_acc_fault_bf),
.dout(ifc_region_acc_fault_f)
);
assign ifu_ic_req_addr_f[31:3] = {miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1] , ic_req_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] };
assign ifu_ic_req_addr_f[31:3] = {
miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1], ic_req_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3]
};
assign ifu_ic_mb_empty = (((miss_state == HIT_U_MISS) | (miss_state == STREAM)) & ~(bus_ifu_wr_en_ff & last_beat)) | ~miss_pending ;
assign ifu_miss_state_idle = (miss_state == IDLE);
@ -657,10 +780,12 @@ if (pt.ICACHE_ECC == 1) begin: icache_ecc_1
rvecc_encode_64 ic_ecc_encode_64_bus (
.din (ifu_bus_rdata_ff[63:0]),
.ecc_out(ic_wr_ecc[6:0]));
.ecc_out(ic_wr_ecc[6:0])
);
rvecc_encode_64 ic_ecc_encode_64_buff (
.din (ic_miss_buff_half[63:0]),
.ecc_out(ic_miss_buff_ecc[6:0]));
.ecc_out(ic_miss_buff_ecc[6:0])
);
for (genvar i = 0; i < pt.ICACHE_BANKS_WAY; i++) begin : ic_wr_data_loop
assign ic_wr_data[i][70:0] = ic_wr_16bytes_data[((71*i)+70):(71*i)];
@ -675,31 +800,31 @@ if (pt.ICACHE_ECC == 1) begin: icache_ecc_1
assign ifu_ic_debug_rd_data_in[70:0] = ic_debug_ict_array_sel_ff ? {2'b0,ictag_debug_rd_data[25:21],32'b0,ictag_debug_rd_data[20:0],{7-pt.ICACHE_STATUS_BITS{1'b0}}, way_status[pt.ICACHE_STATUS_BITS-1:0],3'b0,ic_debug_tag_val_rd_out} :
ic_debug_rd_data[70:0];
rvdffe #(71) ifu_debug_data_ff (.*,
rvdffe #(71) ifu_debug_data_ff (
.*,
.en (debug_data_clken),
.din ({
ifu_ic_debug_rd_data_in[70:0]
}),
.dout({
ifu_ic_debug_rd_data[70:0]
})
.din ({ifu_ic_debug_rd_data_in[70:0]}),
.dout({ifu_ic_debug_rd_data[70:0]})
);
assign ic_wr_16bytes_data[141:0] = ifu_bus_rid_ff[0] ? {ic_wr_ecc[6:0] , ifu_bus_rdata_ff[63:0] , ic_miss_buff_ecc[6:0] , ic_miss_buff_half[63:0] } :
{ic_miss_buff_ecc[6:0] , ic_miss_buff_half[63:0] , ic_wr_ecc[6:0] , ifu_bus_rdata_ff[63:0] } ;
end
else begin : icache_parity_1
end else begin : icache_parity_1
logic [ 3:0] ic_wr_parity;
logic [ 3:0] ic_miss_buff_parity;
logic [135:0] ic_wr_16bytes_data;
logic [ 70:0] ifu_ic_debug_rd_data_in;
for (genvar i = 0; i < 4; i++) begin : DATA_PGEN
rveven_paritygen #(16) par_bus (.data_in (ifu_bus_rdata_ff[((16*i)+15):(16*i)]),
.parity_out(ic_wr_parity[i]));
rveven_paritygen #(16) par_buff (.data_in (ic_miss_buff_half[((16*i)+15):(16*i)]),
.parity_out(ic_miss_buff_parity[i]));
rveven_paritygen #(16) par_bus (
.data_in (ifu_bus_rdata_ff[((16*i)+15):(16*i)]),
.parity_out(ic_wr_parity[i])
);
rveven_paritygen #(16) par_buff (
.data_in (ic_miss_buff_half[((16*i)+15):(16*i)]),
.parity_out(ic_miss_buff_parity[i])
);
end
@ -717,14 +842,11 @@ else begin : icache_parity_1
assign ifu_ic_debug_rd_data_in[70:0] = ic_debug_ict_array_sel_ff ? {6'b0,ictag_debug_rd_data[21],32'b0,ictag_debug_rd_data[20:0],{7-pt.ICACHE_STATUS_BITS{1'b0}},way_status[pt.ICACHE_STATUS_BITS-1:0],3'b0,ic_debug_tag_val_rd_out} :
ic_debug_rd_data[70:0] ;
rvdffe #(71) ifu_debug_data_ff (.*,
rvdffe #(71) ifu_debug_data_ff (
.*,
.en (debug_data_clken),
.din ({
ifu_ic_debug_rd_data_in[70:0]
}),
.dout({
ifu_ic_debug_rd_data[70:0]
})
.din ({ifu_ic_debug_rd_data_in[70:0]}),
.dout({ifu_ic_debug_rd_data[70:0]})
);
assign ic_wr_16bytes_data[135:0] = ifu_bus_rid_ff[0] ? {ic_wr_parity[3:0] , ifu_bus_rdata_ff[63:0] , ic_miss_buff_parity[3:0] , ic_miss_buff_half[63:0] } :
@ -801,13 +923,15 @@ assign two_byte_instr = (ic_data_f[1:0] != 2'b11 ) ;
assign write_fill_data[i] = bus_ifu_wr_en & ( (pt.IFU_BUS_TAG)'(i) == ifu_bus_rsp_tag[pt.IFU_BUS_TAG-1:0]);
rvdffe #(32) byp_data_0_ff (.*,
rvdffe #(32) byp_data_0_ff (
.*,
.en (write_fill_data[i]),
.din (ic_miss_buff_data_in[31:0]),
.dout(ic_miss_buff_data[i*2][31:0])
);
rvdffe #(32) byp_data_1_ff (.*,
rvdffe #(32) byp_data_1_ff (
.*,
.en (write_fill_data[i]),
.din (ic_miss_buff_data_in[63:32]),
.dout(ic_miss_buff_data[i*2+1][31:0])
@ -815,17 +939,21 @@ assign two_byte_instr = (ic_data_f[1:0] != 2'b11 ) ;
assign ic_miss_buff_data_valid_in[i] = write_fill_data[i] ? 1'b1 : (ic_miss_buff_data_valid[i] & ~ic_act_miss_f) ;
rvdff #(1) byp_data_valid_ff (.*,
rvdff #(1) byp_data_valid_ff (
.*,
.clk (active_clk),
.din (ic_miss_buff_data_valid_in[i]),
.dout(ic_miss_buff_data_valid[i]));
.dout(ic_miss_buff_data_valid[i])
);
assign ic_miss_buff_data_error_in[i] = write_fill_data[i] ? bus_ifu_wr_data_error : (ic_miss_buff_data_error[i] & ~ic_act_miss_f) ;
rvdff #(1) byp_data_error_ff (.*,
rvdff #(1) byp_data_error_ff (
.*,
.clk (active_clk),
.din (ic_miss_buff_data_error_in[i]),
.dout(ic_miss_buff_data_error[i]));
.dout(ic_miss_buff_data_error[i])
);
end
/////////////////////////////////////////////////////////////////////////////////////
@ -854,11 +982,19 @@ assign two_byte_instr = (ic_data_f[1:0] != 2'b11 ) ;
assign byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:1] = ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:1];
assign byp_fetch_index_0[pt.ICACHE_BEAT_ADDR_HI:2] = {ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:3],1'b0} ;
assign byp_fetch_index_1[pt.ICACHE_BEAT_ADDR_HI:2] = {ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:3],1'b1} ;
assign byp_fetch_index_0[pt.ICACHE_BEAT_ADDR_HI:2] = {
ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:3], 1'b0
};
assign byp_fetch_index_1[pt.ICACHE_BEAT_ADDR_HI:2] = {
ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:3], 1'b1
};
assign byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3] = ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:3]+1'b1 ;
assign byp_fetch_index_inc_0[pt.ICACHE_BEAT_ADDR_HI:2] = {byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3], 1'b0} ;
assign byp_fetch_index_inc_1[pt.ICACHE_BEAT_ADDR_HI:2] = {byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3], 1'b1} ;
assign byp_fetch_index_inc_0[pt.ICACHE_BEAT_ADDR_HI:2] = {
byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3], 1'b0
};
assign byp_fetch_index_inc_1[pt.ICACHE_BEAT_ADDR_HI:2] = {
byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3], 1'b1
};
assign ifu_byp_data_err_new = (~ifu_fetch_addr_int_f[2] & ~ifu_fetch_addr_int_f[1] & ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] ) |
(~ifu_fetch_addr_int_f[2] & ifu_fetch_addr_int_f[1] & ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] ) |
@ -899,7 +1035,9 @@ assign two_byte_instr = (ic_data_f[1:0] != 2'b11 ) ;
assign other_tag[pt.IFU_BUS_TAG-1:0] = {ifu_bus_rid_ff[pt.IFU_BUS_TAG-1:1], ~ifu_bus_rid_ff[0]};
assign second_half_available = ic_miss_buff_data_valid[other_tag];
assign write_ic_16_bytes = second_half_available & bus_ifu_wr_en_ff;
assign ic_miss_buff_half[63:0] = {ic_miss_buff_data[{other_tag,1'b1}],ic_miss_buff_data[{other_tag,1'b0}] } ;
assign ic_miss_buff_half[63:0] = {
ic_miss_buff_data[{other_tag, 1'b1}], ic_miss_buff_data[{other_tag, 1'b0}]
};
/////////////////////////////////////////////////////////////////////////////////////
@ -917,7 +1055,15 @@ logic perr_sb_write_status ;
rvdffe #(.WIDTH(pt.ICACHE_INDEX_HI-pt.ICACHE_TAG_INDEX_LO+1),.OVERRIDE(1)) perr_dat_ff (.din(ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]), .dout(perr_ic_index_ff[pt.ICACHE_INDEX_HI : pt.ICACHE_TAG_INDEX_LO]), .en(perr_sb_write_status), .*);
rvdffe #(
.WIDTH(pt.ICACHE_INDEX_HI - pt.ICACHE_TAG_INDEX_LO + 1),
.OVERRIDE(1)
) perr_dat_ff (
.din (ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]),
.dout(perr_ic_index_ff[pt.ICACHE_INDEX_HI : pt.ICACHE_TAG_INDEX_LO]),
.en (perr_sb_write_status),
.*
);
assign perr_err_inv_way[pt.ICACHE_NUM_WAYS-1:0] = {pt.ICACHE_NUM_WAYS{perr_sel_invalidate}};
assign iccm_correct_ecc = (perr_state == ECC_CORR);
@ -972,7 +1118,15 @@ logic perr_sb_write_status ;
endcase
end
rvdffs #(($bits(perr_state_t))) perr_state_ff (.clk(active_clk), .din(perr_nxtstate), .dout({perr_state}), .en(perr_state_en), .*);
rvdffs #(($bits(
perr_state_t
))) perr_state_ff (
.clk (active_clk),
.din (perr_nxtstate),
.dout({perr_state}),
.en (perr_state_en),
.*
);
//////////////////////////////////// Create stop fetch State Machine /////////////////////////
//////////////////////////////////// Create stop fetch State Machine /////////////////////////
@ -1020,21 +1174,44 @@ logic perr_sb_write_status ;
end
endcase
end
rvdffs #(($bits(err_stop_state_t))) err_stop_state_ff (.clk(active_clk), .din(err_stop_nxtstate), .dout({err_stop_state}), .en(err_stop_state_en), .*);
rvdffs #(($bits(
err_stop_state_t
))) err_stop_state_ff (
.clk (active_clk),
.din (err_stop_nxtstate),
.dout({err_stop_state}),
.en (err_stop_state_en),
.*
);
assign bus_ifu_bus_clk_en = ifu_bus_clk_en;
rvclkhdr bus_clk_f(.en(bus_ifu_bus_clk_en), .l1clk(busclk), .*);
rvclkhdr bus_clk(.en(bus_ifu_bus_clk_en | dec_tlu_force_halt), .l1clk(busclk_force), .*);
rvclkhdr bus_clk_f (
.en(bus_ifu_bus_clk_en),
.l1clk(busclk),
.*
);
rvclkhdr bus_clk (
.en(bus_ifu_bus_clk_en | dec_tlu_force_halt),
.l1clk(busclk_force),
.*
);
assign scnd_miss_req = scnd_miss_req_q & ~exu_flush_final;
assign ifc_bus_ic_req_ff_in = (ic_act_miss_f | bus_cmd_req_hold | ifu_bus_cmd_valid) & ~dec_tlu_force_halt & ~((bus_cmd_beat_count== {pt.ICACHE_BEAT_BITS{1'b1}}) & ifu_bus_cmd_valid & ifu_bus_cmd_ready & miss_pending);
rvdff_fpga #(1) bus_ic_req_ff2(.*, .clk(busclk_force), .clken(bus_ifu_bus_clk_en | dec_tlu_force_halt), .rawclk(clk), .din(ifc_bus_ic_req_ff_in), .dout(ifu_bus_cmd_valid));
rvdff_fpga #(1) bus_ic_req_ff2 (
.*,
.clk(busclk_force),
.clken(bus_ifu_bus_clk_en | dec_tlu_force_halt),
.rawclk(clk),
.din(ifc_bus_ic_req_ff_in),
.dout(ifu_bus_cmd_valid)
);
assign bus_cmd_req_in = (ic_act_miss_f | bus_cmd_req_hold) & ~bus_cmd_sent & ~dec_tlu_force_halt ; // hold until first command sent
@ -1079,12 +1256,53 @@ logic perr_sb_write_status ;
assign ifu_bus_rvalid_unq = ifu_axi_rvalid;
assign ifu_bus_arvalid = ifu_axi_arvalid;
rvdff_fpga #(1) bus_rdy_ff (.*, .clk(busclk), .clken(bus_ifu_bus_clk_en), .rawclk(clk), .din(ifu_bus_arready_unq), .dout(ifu_bus_arready_unq_ff));
rvdff_fpga #(1) bus_rsp_vld_ff (.*, .clk(busclk), .clken(bus_ifu_bus_clk_en), .rawclk(clk), .din(ifu_bus_rvalid_unq), .dout(ifu_bus_rvalid_unq_ff));
rvdff_fpga #(1) bus_cmd_ff (.*, .clk(busclk), .clken(bus_ifu_bus_clk_en), .rawclk(clk), .din(ifu_bus_arvalid), .dout(ifu_bus_arvalid_ff));
rvdff_fpga #(2) bus_rsp_cmd_ff (.*, .clk(busclk), .clken(bus_ifu_bus_clk_en), .rawclk(clk), .din(ifu_axi_rresp[1:0]), .dout(ifu_bus_rresp_ff[1:0]));
rvdff_fpga #(pt.IFU_BUS_TAG) bus_rsp_tag_ff (.*, .clk(busclk), .clken(bus_ifu_bus_clk_en), .rawclk(clk), .din(ifu_axi_rid[pt.IFU_BUS_TAG-1:0]),.dout(ifu_bus_rid_ff[pt.IFU_BUS_TAG-1:0]));
rvdffe #(64) bus_data_ff (.*, .clk(clk), .din(ifu_axi_rdata[63:0]), .dout(ifu_bus_rdata_ff[63:0]), .en(ifu_bus_clk_en & ifu_axi_rvalid));
rvdff_fpga #(1) bus_rdy_ff (
.*,
.clk(busclk),
.clken(bus_ifu_bus_clk_en),
.rawclk(clk),
.din(ifu_bus_arready_unq),
.dout(ifu_bus_arready_unq_ff)
);
rvdff_fpga #(1) bus_rsp_vld_ff (
.*,
.clk(busclk),
.clken(bus_ifu_bus_clk_en),
.rawclk(clk),
.din(ifu_bus_rvalid_unq),
.dout(ifu_bus_rvalid_unq_ff)
);
rvdff_fpga #(1) bus_cmd_ff (
.*,
.clk(busclk),
.clken(bus_ifu_bus_clk_en),
.rawclk(clk),
.din(ifu_bus_arvalid),
.dout(ifu_bus_arvalid_ff)
);
rvdff_fpga #(2) bus_rsp_cmd_ff (
.*,
.clk(busclk),
.clken(bus_ifu_bus_clk_en),
.rawclk(clk),
.din(ifu_axi_rresp[1:0]),
.dout(ifu_bus_rresp_ff[1:0])
);
rvdff_fpga #(pt.IFU_BUS_TAG) bus_rsp_tag_ff (
.*,
.clk(busclk),
.clken(bus_ifu_bus_clk_en),
.rawclk(clk),
.din(ifu_axi_rid[pt.IFU_BUS_TAG-1:0]),
.dout(ifu_bus_rid_ff[pt.IFU_BUS_TAG-1:0])
);
rvdffe #(64) bus_data_ff (
.*,
.clk (clk),
.din (ifu_axi_rdata[63:0]),
.dout(ifu_bus_rdata_ff[63:0]),
.en (ifu_bus_clk_en & ifu_axi_rvalid)
);
assign ifu_bus_cmd_ready = ifu_axi_arready;
assign ifu_bus_rsp_valid = ifu_axi_rvalid;
@ -1131,7 +1349,14 @@ logic perr_sb_write_status ;
( bus_cmd_sent ) ? (bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0] + 3'b001) :
bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0];
rvdff_fpga #(pt.ICACHE_BEAT_BITS) bus_rd_addr_ff (.*, .clk(busclk_reset), .clken (bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt), .rawclk(clk), .din ({bus_new_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0]}), .dout({bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0]}));
rvdff_fpga #(pt.ICACHE_BEAT_BITS) bus_rd_addr_ff (
.*,
.clk(busclk_reset),
.clken(bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt),
.rawclk(clk),
.din({bus_new_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0]}),
.dout({bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0]})
);
@ -1148,10 +1373,21 @@ logic perr_sb_write_status ;
({pt.ICACHE_BEAT_BITS{bus_hold_cmd_beat_cnt}} & bus_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0]) ;
rvclkhdr bus_clk_reset(.en(bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt), .l1clk(busclk_reset), .*);
rvclkhdr bus_clk_reset (
.en(bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt),
.l1clk(busclk_reset),
.*
);
rvdffs_fpga #(pt.ICACHE_BEAT_BITS) bus_cmd_beat_ff (.*, .clk(busclk_reset), .clken (bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt), .rawclk(clk), .en (bus_cmd_beat_en), .din ({bus_new_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0]}),
.dout({bus_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0]}));
rvdffs_fpga #(pt.ICACHE_BEAT_BITS) bus_cmd_beat_ff (
.*,
.clk(busclk_reset),
.clken(bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt),
.rawclk(clk),
.en(bus_cmd_beat_en),
.din({bus_new_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0]}),
.dout({bus_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0]})
);
assign bus_last_data_beat = uncacheable_miss_ff ? (bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0] == {{pt.ICACHE_BEAT_BITS-1{1'b0}},1'b1}) : (&bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0]);
@ -1162,20 +1398,57 @@ logic perr_sb_write_status ;
assign bus_ifu_wr_en_ff_wo_err = ifu_bus_rvalid_ff & miss_pending & ~uncacheable_miss_ff;
rvdffie #(10) misc_ff
( .*,
rvdffie #(10) misc_ff (
.*,
.clk(free_l2clk),
.din( {ic_act_miss_f, ifu_wr_cumulative_err,exu_flush_final, ic_crit_wd_rdy_new_in,bus_ifu_bus_clk_en, scnd_miss_req_in,bus_cmd_req_in, last_data_recieved_in,
ifc_dma_access_ok_d, dma_iccm_req}),
.dout({ic_act_miss_f_delayed,ifu_wr_data_comb_err_ff, flush_final_f,ic_crit_wd_rdy_new_ff,bus_ifu_bus_clk_en_ff,scnd_miss_req_q, bus_cmd_req_hold,last_data_recieved_ff,
ifc_dma_access_ok_prev,dma_iccm_req_f})
.din({
ic_act_miss_f,
ifu_wr_cumulative_err,
exu_flush_final,
ic_crit_wd_rdy_new_in,
bus_ifu_bus_clk_en,
scnd_miss_req_in,
bus_cmd_req_in,
last_data_recieved_in,
ifc_dma_access_ok_d,
dma_iccm_req
}),
.dout({
ic_act_miss_f_delayed,
ifu_wr_data_comb_err_ff,
flush_final_f,
ic_crit_wd_rdy_new_ff,
bus_ifu_bus_clk_en_ff,
scnd_miss_req_q,
bus_cmd_req_hold,
last_data_recieved_ff,
ifc_dma_access_ok_prev,
dma_iccm_req_f
})
);
rvdffie #(.WIDTH(pt.ICACHE_BEAT_BITS+5),.OVERRIDE(1)) misc1_ff
( .*,
rvdffie #(
.WIDTH(pt.ICACHE_BEAT_BITS + 5),
.OVERRIDE(1)
) misc1_ff (
.*,
.clk(free_l2clk),
.din( {reset_ic_in,sel_mb_addr, bus_new_data_beat_count[pt.ICACHE_BEAT_BITS-1:0],ifc_region_acc_fault_memory_bf,ic_debug_rd_en, ic_debug_rd_en_ff}),
.dout({reset_ic_ff,sel_mb_addr_ff,bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0], ifc_region_acc_fault_memory_f, ic_debug_rd_en_ff,ifu_ic_debug_rd_data_valid})
.din({
reset_ic_in,
sel_mb_addr,
bus_new_data_beat_count[pt.ICACHE_BEAT_BITS-1:0],
ifc_region_acc_fault_memory_bf,
ic_debug_rd_en,
ic_debug_rd_en_ff
}),
.dout({
reset_ic_ff,
sel_mb_addr_ff,
bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0],
ifc_region_acc_fault_memory_f,
ic_debug_rd_en_ff,
ifu_ic_debug_rd_data_valid
})
);
assign reset_tag_valid_for_miss = ic_act_miss_f_delayed & (miss_state == CRIT_BYP_OK) & ~uncacheable_miss_ff;
@ -1229,11 +1502,13 @@ ifc_dma_access_ok_prev,dma_iccm_req_f})
rvecc_encode iccm_ecc_encode0 (
.din(dma_mem_wdata[31:0]),
.ecc_out(dma_mem_ecc[6:0]));
.ecc_out(dma_mem_ecc[6:0])
);
rvecc_encode iccm_ecc_encode1 (
.din(dma_mem_wdata[63:32]),
.ecc_out(dma_mem_ecc[13:7]));
.ecc_out(dma_mem_ecc[13:7])
);
assign iccm_wr_data[77:0] = (iccm_correct_ecc & ~(ifc_dma_access_q_ok & dma_iccm_req)) ? {iccm_ecc_corr_data_ff[38:0], iccm_ecc_corr_data_ff[38:0]} :
{dma_mem_ecc[13:7],dma_mem_wdata[63:32], dma_mem_ecc[6:0],dma_mem_wdata[31:0]};
@ -1242,19 +1517,33 @@ ifc_dma_access_ok_prev,dma_iccm_req_f})
assign iccm_dma_rdata_in[63:0] = iccm_dma_ecc_error_in ? {2{dma_mem_addr[31:0]}} : {iccm_dma_rdata_1_muxed[31:0], iccm_corrected_data[0]};
assign iccm_dma_ecc_error_in = |(iccm_double_ecc_error[1:0]);
rvdffe #(64) dma_data_ff (.*, .clk(clk), .en(iccm_dma_rvalid_in), .din(iccm_dma_rdata_in[63:0]), .dout(iccm_dma_rdata[63:0]));
rvdffie #(11) dma_misc_bits (.*, .clk(free_l2clk), .din({dma_mem_tag[2:0],
rvdffe #(64) dma_data_ff (
.*,
.clk (clk),
.en (iccm_dma_rvalid_in),
.din (iccm_dma_rdata_in[63:0]),
.dout(iccm_dma_rdata[63:0])
);
rvdffie #(11) dma_misc_bits (
.*,
.clk(free_l2clk),
.din({
dma_mem_tag[2:0],
dma_mem_tag_ff[2:0],
dma_mem_addr[3:2],
iccm_dma_rden,
iccm_dma_rvalid_in,
iccm_dma_ecc_error_in }),
.dout({dma_mem_tag_ff[2:0],
iccm_dma_ecc_error_in
}),
.dout({
dma_mem_tag_ff[2:0],
iccm_dma_rtag[2:0],
dma_mem_addr_ff[3:2],
iccm_dma_rvalid_in,
iccm_dma_rvalid,
iccm_dma_ecc_error }));
iccm_dma_ecc_error
})
);
assign iccm_rw_addr[pt.ICCM_BITS-1:1] = ( ifc_dma_access_q_ok & dma_iccm_req & ~iccm_correct_ecc) ? dma_mem_addr[pt.ICCM_BITS-1:1] :
(~(ifc_dma_access_q_ok & dma_iccm_req) & iccm_correct_ecc) ? {iccm_ecc_corr_index_ff[pt.ICCM_BITS-1:2],1'b0} : ifc_fetch_addr_bf[pt.ICCM_BITS-1:1] ;
@ -1282,7 +1571,8 @@ ifc_dma_access_ok_prev,dma_iccm_req_f})
.dout(iccm_corrected_data[i][31:0]),
.ecc_out(iccm_corrected_ecc[i][6:0]),
.single_ecc_error(iccm_single_ecc_error[i]),
.double_ecc_error(iccm_double_ecc_error[i]));
.double_ecc_error(iccm_double_ecc_error[i])
);
end
assign iccm_rd_ecc_single_err = (|iccm_single_ecc_error[1:0] ) & ifc_iccm_access_f & ifc_fetch_req_f;
@ -1297,15 +1587,20 @@ end
assign iccm_error_start = iccm_rd_ecc_single_err;
assign iccm_ecc_corr_index_in[pt.ICCM_BITS-1:2] = iccm_single_ecc_error[0] ? iccm_rw_addr_f[pt.ICCM_BITS-1:2] : iccm_rw_addr_f[pt.ICCM_BITS-1:2] + 1'b1 ;
rvdffie #(pt.ICCM_BITS-1) iccm_index_f (.*, .clk(free_l2clk), .din({iccm_rw_addr[pt.ICCM_BITS-1:2],
iccm_rd_ecc_single_err_hold_in
}),
.dout({iccm_rw_addr_f[pt.ICCM_BITS-1:2],
iccm_rd_ecc_single_err_ff}));
rvdffie #(pt.ICCM_BITS - 1) iccm_index_f (
.*,
.clk (free_l2clk),
.din ({iccm_rw_addr[pt.ICCM_BITS-1:2], iccm_rd_ecc_single_err_hold_in}),
.dout({iccm_rw_addr_f[pt.ICCM_BITS-1:2], iccm_rd_ecc_single_err_ff})
);
rvdffe #((39 + (pt.ICCM_BITS - 2))) ecc_dat0_ff (
.clk(clk),
.din({iccm_corrected_ecc_f_mux[6:0], iccm_corrected_data_f_mux[31:0],iccm_ecc_corr_index_in[pt.ICCM_BITS-1:2]}),
.din({
iccm_corrected_ecc_f_mux[6:0],
iccm_corrected_data_f_mux[31:0],
iccm_ecc_corr_index_in[pt.ICCM_BITS-1:2]
}),
.dout({iccm_ecc_corr_data_ff[38:0], iccm_ecc_corr_index_ff[pt.ICCM_BITS-1:2]}),
.en(iccm_ecc_write_status),
.*
@ -1388,11 +1683,22 @@ if (pt.ICACHE_ENABLE == 1 ) begin: icache_enabled
assign way_status_new_w_debug[pt.ICACHE_STATUS_BITS-1:0] = (ic_debug_wr_en & ic_debug_tag_array) ? (pt.ICACHE_STATUS_BITS == 1) ? ic_debug_wr_data[4] : ic_debug_wr_data[6:4] :
way_status_new[pt.ICACHE_STATUS_BITS-1:0] ;
rvdffie #(.WIDTH(pt.ICACHE_TAG_LO-pt.ICACHE_TAG_INDEX_LO+1+pt.ICACHE_STATUS_BITS),.OVERRIDE(1)) status_misc_ff
(.*,
rvdffie #(
.WIDTH(pt.ICACHE_TAG_LO - pt.ICACHE_TAG_INDEX_LO + 1 + pt.ICACHE_STATUS_BITS),
.OVERRIDE(1)
) status_misc_ff (
.*,
.clk(free_l2clk),
.din({ ifu_status_wr_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO], way_status_wr_en_w_debug, way_status_new_w_debug[pt.ICACHE_STATUS_BITS-1:0]}),
.dout({ifu_status_wr_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO], way_status_wr_en_ff, way_status_new_ff[pt.ICACHE_STATUS_BITS-1:0]} )
.din({
ifu_status_wr_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO],
way_status_wr_en_w_debug,
way_status_new_w_debug[pt.ICACHE_STATUS_BITS-1:0]
}),
.dout({
ifu_status_wr_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO],
way_status_wr_en_ff,
way_status_new_ff[pt.ICACHE_STATUS_BITS-1:0]
})
);
logic [(pt.ICACHE_TAG_DEPTH/8)-1 : 0] way_status_clken;
@ -1401,17 +1707,23 @@ if (pt.ICACHE_ENABLE == 1 ) begin: icache_enabled
for (genvar i = 0; i < pt.ICACHE_TAG_DEPTH / 8; i++) begin : CLK_GRP_WAY_STATUS
assign way_status_clken[i] = (ifu_status_wr_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO+3] == i );
rvclkhdr way_status_cgc ( .en(way_status_clken[i]), .l1clk(way_status_clk[i]), .* );
rvclkhdr way_status_cgc (
.en(way_status_clken[i]),
.l1clk(way_status_clk[i]),
.*
);
for (genvar j = 0; j < 8; j++) begin : WAY_STATUS
rvdffs_fpga #(pt.ICACHE_STATUS_BITS) ic_way_status (.*,
rvdffs_fpga #(pt.ICACHE_STATUS_BITS) ic_way_status (
.*,
.clk(way_status_clk[i]),
.clken(way_status_clken[i]),
.rawclk(clk),
.en(((ifu_status_wr_addr_ff[pt.ICACHE_TAG_INDEX_LO+2:pt.ICACHE_TAG_INDEX_LO] == j) & way_status_wr_en_ff)),
.din(way_status_new_ff[pt.ICACHE_STATUS_BITS-1:0]),
.dout(way_status_out[8*i+j]));
.dout(way_status_out[8*i+j])
);
end // WAY_STATUS
end // CLK_GRP_WAY_STATUS
@ -1431,14 +1743,19 @@ if (pt.ICACHE_ENABLE == 1 ) begin: icache_enabled
assign ic_valid_w_debug = (ic_debug_wr_en & ic_debug_tag_array) ? ic_debug_wr_data[0] : ic_valid;
rvdffie #(pt.ICACHE_TAG_LO-pt.ICACHE_TAG_INDEX_LO+pt.ICACHE_NUM_WAYS+1) tag_addr_ff (.*,
rvdffie #(pt.ICACHE_TAG_LO - pt.ICACHE_TAG_INDEX_LO + pt.ICACHE_NUM_WAYS + 1) tag_addr_ff (
.*,
.clk(free_l2clk),
.din({ifu_ic_rw_int_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO],
.din({
ifu_ic_rw_int_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO],
ifu_tag_wren_w_debug[pt.ICACHE_NUM_WAYS-1:0],
ic_valid_w_debug}),
.dout({ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO],
ic_valid_w_debug
}),
.dout({
ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO],
ifu_tag_wren_ff[pt.ICACHE_NUM_WAYS-1:0],
ic_valid_ff})
ic_valid_ff
})
);
@ -1457,18 +1774,24 @@ if (pt.ICACHE_ENABLE == 1 ) begin: icache_enabled
end
rvclkhdr way_status_cgc ( .en(tag_valid_clken[i][j]), .l1clk(tag_valid_clk[i][j]), .* );
rvclkhdr way_status_cgc (
.en(tag_valid_clken[i][j]),
.l1clk(tag_valid_clk[i][j]),
.*
);
for (genvar k = 0; k < 32; k++) begin : TAG_VALID
rvdffs_fpga #(1) ic_way_tagvalid_dup (.*,
rvdffs_fpga #(1) ic_way_tagvalid_dup (
.*,
.clk(tag_valid_clk[i][j]),
.clken(tag_valid_clken[i][j]),
.rawclk(clk),
.en(((ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == (k + 32*i)) & ifu_tag_wren_ff[j] ) |
((perr_ic_index_ff [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == (k + 32*i)) & perr_err_inv_way[j]) | reset_all_tags),
.din(ic_valid_ff & ~reset_all_tags & ~perr_sel_invalidate),
.dout(ic_tag_valid_out[j][32*i+k]));
.dout(ic_tag_valid_out[j][32*i+k])
);
end
end
end
@ -1523,8 +1846,7 @@ if (pt.ICACHE_ENABLE == 1 ) begin: icache_enabled
({3{replace_way_mb_any[1]}} & {way_status_mb_ff[2] , 1'b0 , 1'b1}) |
({3{replace_way_mb_any[2]}} & {1'b1 ,way_status_mb_ff[1] , 1'b0}) |
({3{replace_way_mb_any[3]}} & {1'b0 ,way_status_mb_ff[1] , 1'b0}) ;
end
else begin : two_ways_plru
end else begin : two_ways_plru
assign replace_way_mb_any[0] = (~way_status_mb_ff & tagv_mb_ff[0] & tagv_mb_ff[1]) | ~tagv_mb_ff[0];
assign replace_way_mb_any[1] = ( way_status_mb_ff & tagv_mb_ff[0] & tagv_mb_ff[1]) | ~tagv_mb_ff[1] & tagv_mb_ff[0];
assign way_status_hit_new[pt.ICACHE_STATUS_BITS-1:0] = ic_rd_hit[0];
@ -1572,22 +1894,32 @@ end
assign ifu_pmu_bus_trxn_in = bus_cmd_sent;
assign ifu_pmu_bus_busy_in = ifu_bus_arvalid_ff & ~ifu_bus_arready_ff & miss_pending;
rvdffie #(9) ifu_pmu_sigs_ff (.*,
rvdffie #(9) ifu_pmu_sigs_ff (
.*,
.clk(free_l2clk),
.din ({ifc_fetch_uncacheable_bf, ifc_fetch_req_qual_bf, dma_sb_err_state, dec_tlu_fence_i_wb,
.din({
ifc_fetch_uncacheable_bf,
ifc_fetch_req_qual_bf,
dma_sb_err_state,
dec_tlu_fence_i_wb,
ifu_pmu_ic_miss_in,
ifu_pmu_ic_hit_in,
ifu_pmu_bus_error_in,
ifu_pmu_bus_busy_in,
ifu_pmu_bus_trxn_in
}),
.dout({fetch_uncacheable_ff, ifc_fetch_req_f_raw, dma_sb_err_state_ff, reset_all_tags,
.dout({
fetch_uncacheable_ff,
ifc_fetch_req_f_raw,
dma_sb_err_state_ff,
reset_all_tags,
ifu_pmu_ic_miss,
ifu_pmu_ic_hit,
ifu_pmu_bus_error,
ifu_pmu_bus_busy,
ifu_pmu_bus_trxn
}));
})
);
///////////////////////////////////////////////////////
@ -1602,23 +1934,25 @@ assign ic_debug_rd_en = dec_tlu_ic_diag_pkt.icache_rd_valid ;
assign ic_debug_wr_en = dec_tlu_ic_diag_pkt.icache_wr_valid;
assign ic_debug_way[pt.ICACHE_NUM_WAYS-1:0] = {(ic_debug_way_enc[1:0] == 2'b11),
assign ic_debug_way[pt.ICACHE_NUM_WAYS-1:0] = {
(ic_debug_way_enc[1:0] == 2'b11),
(ic_debug_way_enc[1:0] == 2'b10),
(ic_debug_way_enc[1:0] == 2'b01),
(ic_debug_way_enc[1:0] == 2'b00) };
(ic_debug_way_enc[1:0] == 2'b00)
};
assign ic_debug_tag_wr_en[pt.ICACHE_NUM_WAYS-1:0] = {pt.ICACHE_NUM_WAYS{ic_debug_wr_en & ic_debug_tag_array}} & ic_debug_way[pt.ICACHE_NUM_WAYS-1:0] ;
assign ic_debug_ict_array_sel_in = ic_debug_rd_en & ic_debug_tag_array;
rvdff_fpga #(01+pt.ICACHE_NUM_WAYS) ifu_debug_sel_ff (.*, .clk (debug_c1_clk),
.clken(debug_c1_clken), .rawclk(clk),
.din ({ic_debug_ict_array_sel_in,
ic_debug_way[pt.ICACHE_NUM_WAYS-1:0]
}),
.dout({ic_debug_ict_array_sel_ff,
ic_debug_way_ff[pt.ICACHE_NUM_WAYS-1:0]
}));
rvdff_fpga #(01 + pt.ICACHE_NUM_WAYS) ifu_debug_sel_ff (
.*,
.clk(debug_c1_clk),
.clken(debug_c1_clken),
.rawclk(clk),
.din({ic_debug_ict_array_sel_in, ic_debug_way[pt.ICACHE_NUM_WAYS-1:0]}),
.dout({ic_debug_ict_array_sel_ff, ic_debug_way_ff[pt.ICACHE_NUM_WAYS-1:0]})
);

View File

@ -73,12 +73,17 @@ module el2_ifu_tb_memread;
always @(negedge clk) begin
if (clk_count > 3 & error) begin
$display("clock: %d compressed %h error actual %h expected %h",clk_count,compressed_din,actual,expected_val);
$display("clock: %d compressed %h error actual %h expected %h", clk_count, compressed_din,
actual, expected_val);
end
end
el2_ifu_compress_ctl align (.*,.din(compressed_din[15:0]),.dout(actual[31:0]));
el2_ifu_compress_ctl align (
.*,
.din (compressed_din[15:0]),
.dout(actual[31:0])
);
assign error = actual[31:0] != expected_val[31:0];

View File

@ -92,7 +92,8 @@ import el2_pkg::*;
logic [7:0] master_wstrb;
typedef enum logic [1:0] { IDLE = 2'b00, // Nothing in the buffer. No commands yet recieved
typedef enum logic [1:0] {
IDLE = 2'b00, // Nothing in the buffer. No commands yet recieved
WR = 2'b01, // Write Command recieved
RD = 2'b10, // Read Command recieved
PEND = 2'b11 // Waiting on Read Data from core
@ -161,7 +162,17 @@ import el2_pkg::*;
endcase
end // always_comb begin
rvdffs_fpga #($bits(state_t)) state_reg (.*, .din(buf_nxtstate), .dout({buf_state}), .en(buf_state_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk));
rvdffs_fpga #($bits(
state_t
)) state_reg (
.*,
.din(buf_nxtstate),
.dout({buf_state}),
.en(buf_state_en),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk)
);
assign master_wstrb[7:0] = ({8{ahb_hsize_q[2:0] == 3'b0}} & (8'b1 << ahb_haddr_q[2:0])) |
({8{ahb_hsize_q[2:0] == 3'b1}} & (8'b11 << ahb_haddr_q[2:0])) |
@ -186,20 +197,94 @@ import el2_pkg::*;
(ahb_hresp_q & ~ahb_hready_q);
// Buffer signals - needed for the read data and ECC error response
rvdff_fpga #(.WIDTH(64)) buf_rdata_ff (.din(axi_rdata[63:0]), .dout(buf_rdata[63:0]), .clk(buf_rdata_clk), .clken(buf_rdata_clk_en), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) buf_read_error_ff(.din(buf_read_error_in), .dout(buf_read_error), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*); // buf_read_error will be high only one cycle
rvdff_fpga #(
.WIDTH(64)
) buf_rdata_ff (
.din(axi_rdata[63:0]),
.dout(buf_rdata[63:0]),
.clk(buf_rdata_clk),
.clken(buf_rdata_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) buf_read_error_ff (
.din(buf_read_error_in),
.dout(buf_read_error),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
); // buf_read_error will be high only one cycle
// All the Master signals are captured before presenting it to the command buffer. We check for Hresp before sending it to the cmd buffer.
rvdff_fpga #(.WIDTH(1)) hresp_ff (.din(ahb_hresp), .dout(ahb_hresp_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) hready_ff (.din(ahb_hready), .dout(ahb_hready_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(2)) htrans_ff (.din(ahb_htrans_in[1:0]), .dout(ahb_htrans_q[1:0]), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(3)) hsize_ff (.din(ahb_hsize[2:0]), .dout(ahb_hsize_q[2:0]), .clk(ahb_addr_clk), .clken(ahb_addr_clk_en), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) hwrite_ff (.din(ahb_hwrite), .dout(ahb_hwrite_q), .clk(ahb_addr_clk), .clken(ahb_addr_clk_en), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(32)) haddr_ff (.din(ahb_haddr[31:0]), .dout(ahb_haddr_q[31:0]), .clk(ahb_addr_clk), .clken(ahb_addr_clk_en), .rawclk(clk), .*);
rvdff_fpga #(
.WIDTH(1)
) hresp_ff (
.din(ahb_hresp),
.dout(ahb_hresp_q),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) hready_ff (
.din(ahb_hready),
.dout(ahb_hready_q),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(2)
) htrans_ff (
.din(ahb_htrans_in[1:0]),
.dout(ahb_htrans_q[1:0]),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(3)
) hsize_ff (
.din(ahb_hsize[2:0]),
.dout(ahb_hsize_q[2:0]),
.clk(ahb_addr_clk),
.clken(ahb_addr_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) hwrite_ff (
.din(ahb_hwrite),
.dout(ahb_hwrite_q),
.clk(ahb_addr_clk),
.clken(ahb_addr_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(32)
) haddr_ff (
.din(ahb_haddr[31:0]),
.dout(ahb_haddr_q[31:0]),
.clk(ahb_addr_clk),
.clken(ahb_addr_clk_en),
.rawclk(clk),
.*
);
// Address check dccm
rvrangecheck #(.CCM_SADR(pt.DCCM_SADR),
.CCM_SIZE(pt.DCCM_SIZE)) addr_dccm_rangecheck (
rvrangecheck #(
.CCM_SADR(pt.DCCM_SADR),
.CCM_SIZE(pt.DCCM_SIZE)
) addr_dccm_rangecheck (
.addr(ahb_haddr_q[31:0]),
.in_range(ahb_addr_in_dccm),
.in_region(ahb_addr_in_dccm_region_nc)
@ -207,8 +292,10 @@ import el2_pkg::*;
// Address check iccm
if (pt.ICCM_ENABLE == 1) begin : GenICCM
rvrangecheck #(.CCM_SADR(pt.ICCM_SADR),
.CCM_SIZE(pt.ICCM_SIZE)) addr_iccm_rangecheck (
rvrangecheck #(
.CCM_SADR(pt.ICCM_SADR),
.CCM_SIZE(pt.ICCM_SIZE)
) addr_iccm_rangecheck (
.addr(ahb_haddr_q[31:0]),
.in_range(ahb_addr_in_iccm),
.in_region(ahb_addr_in_iccm_region_nc)
@ -219,8 +306,10 @@ import el2_pkg::*;
end
// PIC memory address check
rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR),
.CCM_SIZE(pt.PIC_SIZE)) addr_pic_rangecheck (
rvrangecheck #(
.CCM_SADR(pt.PIC_BASE_ADDR),
.CCM_SIZE(pt.PIC_SIZE)
) addr_pic_rangecheck (
.addr(ahb_haddr_q[31:0]),
.in_range(ahb_addr_in_pic),
.in_region(ahb_addr_in_pic_region_nc)
@ -230,12 +319,69 @@ import el2_pkg::*;
assign cmdbuf_rst = (((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)) & ~cmdbuf_wr_en) | (ahb_hresp & ~cmdbuf_write);
assign cmdbuf_full = (cmdbuf_vld & ~((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)));
rvdffsc_fpga #(.WIDTH(1)) cmdbuf_vldff (.din(1'b1), .dout(cmdbuf_vld), .en(cmdbuf_wr_en), .clear(cmdbuf_rst), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(1)) cmdbuf_writeff (.din(ahb_hwrite_q), .dout(cmdbuf_write), .en(cmdbuf_wr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(2)) cmdbuf_sizeff (.din(ahb_hsize_q[1:0]), .dout(cmdbuf_size[1:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(8)) cmdbuf_wstrbff (.din(master_wstrb[7:0]), .dout(cmdbuf_wstrb[7:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffe #(.WIDTH(32)) cmdbuf_addrff (.din(ahb_haddr_q[31:0]), .dout(cmdbuf_addr[31:0]), .en(cmdbuf_wr_en & bus_clk_en), .clk(clk), .*);
rvdffe #(.WIDTH(64)) cmdbuf_wdataff (.din(ahb_hwdata[63:0]), .dout(cmdbuf_wdata[63:0]), .en(cmdbuf_wr_en & bus_clk_en), .clk(clk), .*);
rvdffsc_fpga #(
.WIDTH(1)
) cmdbuf_vldff (
.din(1'b1),
.dout(cmdbuf_vld),
.en(cmdbuf_wr_en),
.clear(cmdbuf_rst),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(1)
) cmdbuf_writeff (
.din(ahb_hwrite_q),
.dout(cmdbuf_write),
.en(cmdbuf_wr_en),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(2)
) cmdbuf_sizeff (
.din(ahb_hsize_q[1:0]),
.dout(cmdbuf_size[1:0]),
.en(cmdbuf_wr_en),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(8)
) cmdbuf_wstrbff (
.din(master_wstrb[7:0]),
.dout(cmdbuf_wstrb[7:0]),
.en(cmdbuf_wr_en),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffe #(
.WIDTH(32)
) cmdbuf_addrff (
.din (ahb_haddr_q[31:0]),
.dout(cmdbuf_addr[31:0]),
.en (cmdbuf_wr_en & bus_clk_en),
.clk (clk),
.*
);
rvdffe #(
.WIDTH(64)
) cmdbuf_wdataff (
.din (ahb_hwdata[63:0]),
.dout(cmdbuf_wdata[63:0]),
.en (cmdbuf_wr_en & bus_clk_en),
.clk (clk),
.*
);
// AXI Write Command Channel
assign axi_awvalid = cmdbuf_vld & cmdbuf_write;
@ -267,8 +413,20 @@ import el2_pkg::*;
assign ahb_addr_clk_en = bus_clk_en & (ahb_hready & ahb_htrans[1]);
assign buf_rdata_clk_en = bus_clk_en & buf_rdata_en;
rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*);
rvclkhdr ahb_addr_cgc (.en(ahb_addr_clk_en), .l1clk(ahb_addr_clk), .*);
rvclkhdr buf_rdata_cgc (.en(buf_rdata_clk_en), .l1clk(buf_rdata_clk), .*);
rvclkhdr bus_cgc (
.en(bus_clk_en),
.l1clk(bus_clk),
.*
);
rvclkhdr ahb_addr_cgc (
.en(ahb_addr_clk_en),
.l1clk(ahb_addr_clk),
.*
);
rvclkhdr buf_rdata_cgc (
.en(buf_rdata_clk_en),
.l1clk(buf_rdata_clk),
.*
);
endmodule // ahb_to_axi4

View File

@ -24,8 +24,9 @@
module axi4_to_ahb
import el2_pkg::*;
#(
`include "el2_param.vh"
,parameter TAG = 1) (
`include "el2_param.vh",
parameter TAG = 1
) (
input clk,
input free_clk,
@ -88,7 +89,16 @@ import el2_pkg::*;
localparam ID = 1;
localparam PRTY = 1;
typedef enum logic [2:0] {IDLE=3'b000, CMD_RD=3'b001, CMD_WR=3'b010, DATA_RD=3'b011, DATA_WR=3'b100, DONE=3'b101, STREAM_RD=3'b110, STREAM_ERR_RD=3'b111} state_t;
typedef enum logic [2:0] {
IDLE = 3'b000,
CMD_RD = 3'b001,
CMD_WR = 3'b010,
DATA_RD = 3'b011,
DATA_WR = 3'b100,
DONE = 3'b101,
STREAM_RD = 3'b110,
STREAM_ERR_RD = 3'b111
} state_t;
state_t buf_state, buf_nxtstate;
logic slave_valid;
@ -205,7 +215,8 @@ import el2_pkg::*;
endfunction // get_write_addr
// Function to get the next byte pointer
function automatic logic [2:0] get_nxtbyte_ptr (logic [2:0] current_byte_ptr, logic [7:0] byteen, logic get_next);
function automatic logic [2:0] get_nxtbyte_ptr(logic [2:0] current_byte_ptr, logic [7:0] byteen,
logic get_next);
logic [2:0] start_ptr;
logic found;
found = '0;
@ -222,7 +233,14 @@ import el2_pkg::*;
// Create bus synchronized version of force halt
assign dec_tlu_force_halt_bus = dec_tlu_force_halt | dec_tlu_force_halt_bus_q;
assign dec_tlu_force_halt_bus_ns = ~bus_clk_en & dec_tlu_force_halt_bus;
rvdff #(.WIDTH(1)) force_halt_busff(.din(dec_tlu_force_halt_bus_ns), .dout(dec_tlu_force_halt_bus_q), .clk(free_clk), .*);
rvdff #(
.WIDTH(1)
) force_halt_busff (
.din (dec_tlu_force_halt_bus_ns),
.dout(dec_tlu_force_halt_bus_q),
.clk (free_clk),
.*
);
// Write buffer
assign wrbuf_en = axi_awvalid & axi_awready & master_ready;
@ -284,7 +302,8 @@ import el2_pkg::*;
buf_wr_en = buf_state_en;
buf_data_wr_en = buf_state_en & (buf_nxtstate == CMD_WR);
buf_cmd_byte_ptr_en = buf_state_en;
buf_cmd_byte_ptr[2:0] = buf_write_in ? get_nxtbyte_ptr(3'b0,buf_byteen_in[7:0],1'b0) : master_addr[2:0];
buf_cmd_byte_ptr[2:0] = buf_write_in ? get_nxtbyte_ptr(3'b0, buf_byteen_in[7:0], 1'b0) :
master_addr[2:0];
bypass_en = buf_state_en;
rd_bypass_idle = bypass_en & (buf_nxtstate == CMD_RD);
ahb_htrans[1:0] = {2{bypass_en}} & 2'b10;
@ -338,9 +357,11 @@ import el2_pkg::*;
buf_state_en = trxn_done;
buf_cmd_byte_ptr_en = buf_state_en;
slvbuf_wr_en = buf_state_en;
buf_cmd_byte_ptr = trxn_done ? get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1) : buf_cmd_byte_ptrQ;
buf_cmd_byte_ptr = trxn_done ?
get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0], buf_byteen[7:0], 1'b1) : buf_cmd_byte_ptrQ;
cmd_done = trxn_done & (buf_aligned | (buf_cmd_byte_ptrQ == 3'b111) |
(buf_byteen[get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1)] == 1'b0));
(buf_byteen[get_nxtbyte_ptr(
buf_cmd_byte_ptrQ[2:0], buf_byteen[7:0], 1'b1)] == 1'b0));
ahb_htrans[1:0] = {2{~(cmd_done | cmd_doneQ)}} & 2'b10;
end
DATA_WR: begin
@ -356,15 +377,16 @@ import el2_pkg::*;
buf_data_wr_en = buf_wr_en;
cmd_done = (ahb_hresp_q | (ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) &
((buf_cmd_byte_ptrQ == 3'b111) | (buf_byteen[get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1)] == 1'b0))));
((buf_cmd_byte_ptrQ == 3'b111) | (buf_byteen[get_nxtbyte_ptr(
buf_cmd_byte_ptrQ[2:0], buf_byteen[7:0], 1'b1)] == 1'b0))));
bypass_en = buf_state_en & buf_write_in & (buf_nxtstate == CMD_WR); // Only bypass for writes for the time being
ahb_htrans[1:0] = {2{(~(cmd_done | cmd_doneQ) | bypass_en)}} & 2'b10;
slave_valid_pre = buf_state_en & (buf_nxtstate != DONE);
trxn_done = ahb_hready_q & ahb_hwrite_q & (ahb_htrans_q[1:0] != 2'b0);
buf_cmd_byte_ptr_en = trxn_done | bypass_en;
buf_cmd_byte_ptr = bypass_en ? get_nxtbyte_ptr(3'b0,buf_byteen_in[7:0],1'b0) :
trxn_done ? get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0],buf_byteen[7:0],1'b1) : buf_cmd_byte_ptrQ;
buf_cmd_byte_ptr = bypass_en ? get_nxtbyte_ptr(3'b0, buf_byteen_in[7:0], 1'b0) : trxn_done ?
get_nxtbyte_ptr(buf_cmd_byte_ptrQ[2:0], buf_byteen[7:0], 1'b1) : buf_cmd_byte_ptrQ;
end
DONE: begin
buf_nxtstate = IDLE;
@ -378,11 +400,15 @@ import el2_pkg::*;
assign buf_rst = dec_tlu_force_halt_bus;
assign cmd_done_rst = slave_valid_pre;
assign buf_addr_in[31:3] = master_addr[31:3];
assign buf_addr_in[2:0] = (buf_aligned_in & (master_opc[2:1] == 2'b01)) ? get_write_addr(master_byteen[7:0]) : master_addr[2:0];
assign buf_addr_in[2:0] = (buf_aligned_in & (master_opc[2:1] == 2'b01)) ? get_write_addr(
master_byteen[7:0]
) : master_addr[2:0];
assign buf_tag_in[TAG-1:0] = master_tag[TAG-1:0];
assign buf_byteen_in[7:0] = wrbuf_byteen[7:0];
assign buf_data_in[63:0] = (buf_state == DATA_RD) ? ahb_hrdata_q[63:0] : master_wdata[63:0];
assign buf_size_in[1:0] = (buf_aligned_in & (master_size[1:0] == 2'b11) & (master_opc[2:1] == 2'b01)) ? get_write_size(master_byteen[7:0]) : master_size[1:0];
assign buf_size_in[1:0] = (buf_aligned_in & (master_size[1:0] == 2'b11) & (master_opc[2:1] == 2'b01)) ? get_write_size(
master_byteen[7:0]
) : master_size[1:0];
assign buf_aligned_in = (master_opc[2:0] == 3'b0) | // reads are always aligned since they are either DW or sideeffects
(master_size[1:0] == 2'b0) | (master_size[1:0] == 2'b01) | (master_size[1:0] == 2'b10) | // Always aligned for Byte/HW/Word since they can be only for non-idempotent. IFU/SB are always aligned
((master_size[1:0] == 2'b11) &
@ -409,46 +435,309 @@ import el2_pkg::*;
assign last_addr_en = (ahb_htrans[1:0] != 2'b0) & ahb_hready & ahb_hwrite;
rvdffsc_fpga #(.WIDTH(1)) wrbuf_vldff (.din(1'b1), .dout(wrbuf_vld), .en(wrbuf_en), .clear(wrbuf_rst), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffsc_fpga #(.WIDTH(1)) wrbuf_data_vldff(.din(1'b1), .dout(wrbuf_data_vld), .en(wrbuf_data_en), .clear(wrbuf_rst), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(TAG)) wrbuf_tagff (.din(axi_awid[TAG-1:0]), .dout(wrbuf_tag[TAG-1:0]), .en(wrbuf_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(3)) wrbuf_sizeff (.din(axi_awsize[2:0]), .dout(wrbuf_size[2:0]), .en(wrbuf_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffe #(.WIDTH(32)) wrbuf_addrff (.din(axi_awaddr[31:0]), .dout(wrbuf_addr[31:0]), .en(wrbuf_en & bus_clk_en), .clk(clk), .*);
rvdffe #(.WIDTH(64)) wrbuf_dataff (.din(axi_wdata[63:0]), .dout(wrbuf_data[63:0]), .en(wrbuf_data_en & bus_clk_en), .clk(clk), .*);
rvdffs_fpga #(.WIDTH(8)) wrbuf_byteenff (.din(axi_wstrb[7:0]), .dout(wrbuf_byteen[7:0]), .en(wrbuf_data_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffsc_fpga #(
.WIDTH(1)
) wrbuf_vldff (
.din(1'b1),
.dout(wrbuf_vld),
.en(wrbuf_en),
.clear(wrbuf_rst),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffsc_fpga #(
.WIDTH(1)
) wrbuf_data_vldff (
.din(1'b1),
.dout(wrbuf_data_vld),
.en(wrbuf_data_en),
.clear(wrbuf_rst),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(TAG)
) wrbuf_tagff (
.din(axi_awid[TAG-1:0]),
.dout(wrbuf_tag[TAG-1:0]),
.en(wrbuf_en),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(3)
) wrbuf_sizeff (
.din(axi_awsize[2:0]),
.dout(wrbuf_size[2:0]),
.en(wrbuf_en),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffe #(
.WIDTH(32)
) wrbuf_addrff (
.din (axi_awaddr[31:0]),
.dout(wrbuf_addr[31:0]),
.en (wrbuf_en & bus_clk_en),
.clk (clk),
.*
);
rvdffe #(
.WIDTH(64)
) wrbuf_dataff (
.din (axi_wdata[63:0]),
.dout(wrbuf_data[63:0]),
.en (wrbuf_data_en & bus_clk_en),
.clk (clk),
.*
);
rvdffs_fpga #(
.WIDTH(8)
) wrbuf_byteenff (
.din(axi_wstrb[7:0]),
.dout(wrbuf_byteen[7:0]),
.en(wrbuf_data_en),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(.WIDTH(32)) last_bus_addrff (.din(ahb_haddr[31:0]), .dout(last_bus_addr[31:0]), .en(last_addr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(
.WIDTH(32)
) last_bus_addrff (
.din(ahb_haddr[31:0]),
.dout(last_bus_addr[31:0]),
.en(last_addr_en),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffsc_fpga #(.WIDTH($bits(state_t))) buf_state_ff (.din(buf_nxtstate), .dout({buf_state}), .en(buf_state_en), .clear(buf_rst), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(1)) buf_writeff (.din(buf_write_in), .dout(buf_write), .en(buf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(TAG)) buf_tagff (.din(buf_tag_in[TAG-1:0]), .dout(buf_tag[TAG-1:0]), .en(buf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*);
rvdffe #(.WIDTH(32)) buf_addrff (.din(buf_addr_in[31:0]), .dout(buf_addr[31:0]), .en(buf_wr_en & bus_clk_en), .clk(clk), .*);
rvdffs_fpga #(.WIDTH(2)) buf_sizeff (.din(buf_size_in[1:0]), .dout(buf_size[1:0]), .en(buf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(1)) buf_alignedff (.din(buf_aligned_in), .dout(buf_aligned), .en(buf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(8)) buf_byteenff (.din(buf_byteen_in[7:0]), .dout(buf_byteen[7:0]), .en(buf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*);
rvdffe #(.WIDTH(64)) buf_dataff (.din(buf_data_in[63:0]), .dout(buf_data[63:0]), .en(buf_data_wr_en & bus_clk_en), .clk(clk), .*);
rvdffsc_fpga #(
.WIDTH($bits(state_t))
) buf_state_ff (
.din(buf_nxtstate),
.dout({buf_state}),
.en(buf_state_en),
.clear(buf_rst),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(1)
) buf_writeff (
.din(buf_write_in),
.dout(buf_write),
.en(buf_wr_en),
.clk(buf_clk),
.clken(buf_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(TAG)
) buf_tagff (
.din(buf_tag_in[TAG-1:0]),
.dout(buf_tag[TAG-1:0]),
.en(buf_wr_en),
.clk(buf_clk),
.clken(buf_clken),
.rawclk(clk),
.*
);
rvdffe #(
.WIDTH(32)
) buf_addrff (
.din (buf_addr_in[31:0]),
.dout(buf_addr[31:0]),
.en (buf_wr_en & bus_clk_en),
.clk (clk),
.*
);
rvdffs_fpga #(
.WIDTH(2)
) buf_sizeff (
.din(buf_size_in[1:0]),
.dout(buf_size[1:0]),
.en(buf_wr_en),
.clk(buf_clk),
.clken(buf_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(1)
) buf_alignedff (
.din(buf_aligned_in),
.dout(buf_aligned),
.en(buf_wr_en),
.clk(buf_clk),
.clken(buf_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(8)
) buf_byteenff (
.din(buf_byteen_in[7:0]),
.dout(buf_byteen[7:0]),
.en(buf_wr_en),
.clk(buf_clk),
.clken(buf_clken),
.rawclk(clk),
.*
);
rvdffe #(
.WIDTH(64)
) buf_dataff (
.din (buf_data_in[63:0]),
.dout(buf_data[63:0]),
.en (buf_data_wr_en & bus_clk_en),
.clk (clk),
.*
);
rvdffs_fpga #(.WIDTH(1)) slvbuf_writeff (.din(buf_write), .dout(slvbuf_write), .en(slvbuf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(TAG)) slvbuf_tagff (.din(buf_tag[TAG-1:0]), .dout(slvbuf_tag[TAG-1:0]), .en(slvbuf_wr_en), .clk(buf_clk), .clken(buf_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(1)) slvbuf_errorff (.din(slvbuf_error_in), .dout(slvbuf_error), .en(slvbuf_error_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(
.WIDTH(1)
) slvbuf_writeff (
.din(buf_write),
.dout(slvbuf_write),
.en(slvbuf_wr_en),
.clk(buf_clk),
.clken(buf_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(TAG)
) slvbuf_tagff (
.din(buf_tag[TAG-1:0]),
.dout(slvbuf_tag[TAG-1:0]),
.en(slvbuf_wr_en),
.clk(buf_clk),
.clken(buf_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(1)
) slvbuf_errorff (
.din(slvbuf_error_in),
.dout(slvbuf_error),
.en(slvbuf_error_en),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffsc_fpga #(.WIDTH(1)) buf_cmd_doneff (.din(1'b1), .dout(cmd_doneQ), .en(cmd_done), .clear(cmd_done_rst), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(3)) buf_cmd_byte_ptrff (.din(buf_cmd_byte_ptr[2:0]), .dout(buf_cmd_byte_ptrQ[2:0]), .en(buf_cmd_byte_ptr_en), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdffsc_fpga #(
.WIDTH(1)
) buf_cmd_doneff (
.din(1'b1),
.dout(cmd_doneQ),
.en(cmd_done),
.clear(cmd_done_rst),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(3)
) buf_cmd_byte_ptrff (
.din(buf_cmd_byte_ptr[2:0]),
.dout(buf_cmd_byte_ptrQ[2:0]),
.en(buf_cmd_byte_ptr_en),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(.WIDTH(1)) hready_ff (.din(ahb_hready), .dout(ahb_hready_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(2)) htrans_ff (.din(ahb_htrans[1:0]), .dout(ahb_htrans_q[1:0]), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) hwrite_ff (.din(ahb_hwrite), .dout(ahb_hwrite_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) hresp_ff (.din(ahb_hresp), .dout(ahb_hresp_q), .clk(bus_clk), .clken(bus_clk_en), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(64)) hrdata_ff (.din(ahb_hrdata[63:0]), .dout(ahb_hrdata_q[63:0]), .clk(ahbm_data_clk), .clken(ahbm_data_clken), .rawclk(clk), .*);
rvdff_fpga #(
.WIDTH(1)
) hready_ff (
.din(ahb_hready),
.dout(ahb_hready_q),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(2)
) htrans_ff (
.din(ahb_htrans[1:0]),
.dout(ahb_htrans_q[1:0]),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) hwrite_ff (
.din(ahb_hwrite),
.dout(ahb_hwrite_q),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) hresp_ff (
.din(ahb_hresp),
.dout(ahb_hresp_q),
.clk(bus_clk),
.clken(bus_clk_en),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(64)
) hrdata_ff (
.din(ahb_hrdata[63:0]),
.dout(ahb_hrdata_q[63:0]),
.clk(ahbm_data_clk),
.clken(ahbm_data_clken),
.rawclk(clk),
.*
);
// Clock headers
// clock enables for ahbm addr/data
assign buf_clken = bus_clk_en & (buf_wr_en | slvbuf_wr_en | clk_override);
assign ahbm_data_clken = bus_clk_en & ((buf_state != IDLE) | clk_override);
rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*);
rvclkhdr buf_cgc (.en(buf_clken), .l1clk(buf_clk), .*);
rvclkhdr ahbm_data_cgc (.en(ahbm_data_clken), .l1clk(ahbm_data_clk), .*);
rvclkhdr bus_cgc (
.en(bus_clk_en),
.l1clk(bus_clk),
.*
);
rvclkhdr buf_cgc (
.en(buf_clken),
.l1clk(buf_clk),
.*
);
rvclkhdr ahbm_data_cgc (
.en(ahbm_data_clken),
.l1clk(ahbm_data_clk),
.*
);
endmodule // axi4_to_ahb

View File

@ -16,8 +16,10 @@
// all flops call the rvdff flop
module rvdff #( parameter WIDTH=1, SHORT=0 )
(
module rvdff #(
parameter WIDTH = 1,
SHORT = 0
) (
input logic [WIDTH-1:0] din,
input logic clk,
input logic rst_l,
@ -27,8 +29,7 @@ module rvdff #( parameter WIDTH=1, SHORT=0 )
if (SHORT == 1) begin
assign dout = din;
end
else begin
end else begin
`ifdef RV_CLOCKGATE
always @(posedge tb_top.clk) begin
#0 $strobe("CG: %0t %m din %x dout %x clk %b width %d", $time, din, dout, clk, WIDTH);
@ -36,18 +37,18 @@ else begin
`endif
always_ff @(posedge clk or negedge rst_l) begin
if (rst_l == 0)
dout[WIDTH-1:0] <= 0;
else
dout[WIDTH-1:0] <= din[WIDTH-1:0];
if (rst_l == 0) dout[WIDTH-1:0] <= 0;
else dout[WIDTH-1:0] <= din[WIDTH-1:0];
end
end
endmodule
// rvdff with 2:1 input mux to flop din iff sel==1
module rvdffs #( parameter WIDTH=1, SHORT=0 )
(
module rvdffs #(
parameter WIDTH = 1,
SHORT = 0
) (
input logic [WIDTH-1:0] din,
input logic en,
input logic clk,
@ -57,16 +58,20 @@ module rvdffs #( parameter WIDTH=1, SHORT=0 )
if (SHORT == 1) begin : genblock
assign dout = din;
end
else begin : genblock
rvdff #(WIDTH) dffs (.din((en) ? din[WIDTH-1:0] : dout[WIDTH-1:0]), .*);
end else begin : genblock
rvdff #(WIDTH) dffs (
.din((en) ? din[WIDTH-1:0] : dout[WIDTH-1:0]),
.*
);
end
endmodule
// rvdff with en and clear
module rvdffsc #( parameter WIDTH=1, SHORT=0 )
(
module rvdffsc #(
parameter WIDTH = 1,
SHORT = 0
) (
input logic [WIDTH-1:0] din,
input logic en,
input logic clear,
@ -78,16 +83,20 @@ module rvdffsc #( parameter WIDTH=1, SHORT=0 )
logic [WIDTH-1:0] din_new;
if (SHORT == 1) begin
assign dout = din;
end
else begin
end else begin
assign din_new = {WIDTH{~clear}} & (en ? din[WIDTH-1:0] : dout[WIDTH-1:0]);
rvdff #(WIDTH) dffsc (.din(din_new[WIDTH-1:0]), .*);
rvdff #(WIDTH) dffsc (
.din(din_new[WIDTH-1:0]),
.*
);
end
endmodule
// _fpga versions
module rvdff_fpga #( parameter WIDTH=1, SHORT=0 )
(
module rvdff_fpga #(
parameter WIDTH = 1,
SHORT = 0
) (
input logic [WIDTH-1:0] din,
input logic clk,
input logic clken,
@ -99,15 +108,16 @@ module rvdff_fpga #( parameter WIDTH=1, SHORT=0 )
if (SHORT == 1) begin
assign dout = din;
end
else begin
end else begin
rvdff #(WIDTH) dff (.*);
end
endmodule
// rvdff with 2:1 input mux to flop din iff sel==1
module rvdffs_fpga #( parameter WIDTH=1, SHORT=0 )
(
module rvdffs_fpga #(
parameter WIDTH = 1,
SHORT = 0
) (
input logic [WIDTH-1:0] din,
input logic en,
input logic clk,
@ -120,16 +130,17 @@ module rvdffs_fpga #( parameter WIDTH=1, SHORT=0 )
if (SHORT == 1) begin : genblock
assign dout = din;
end
else begin : genblock
end else begin : genblock
rvdffs #(WIDTH) dffs (.*);
end
endmodule
// rvdff with en and clear
module rvdffsc_fpga #( parameter WIDTH=1, SHORT=0 )
(
module rvdffsc_fpga #(
parameter WIDTH = 1,
SHORT = 0
) (
input logic [WIDTH-1:0] din,
input logic en,
input logic clear,
@ -144,15 +155,17 @@ module rvdffsc_fpga #( parameter WIDTH=1, SHORT=0 )
logic [WIDTH-1:0] din_new;
if (SHORT == 1) begin
assign dout = din;
end
else begin
end else begin
rvdffsc #(WIDTH) dffsc (.*);
end
endmodule
module rvdffe #( parameter WIDTH=1, SHORT=0, OVERRIDE=0 )
(
module rvdffe #(
parameter WIDTH = 1,
SHORT = 0,
OVERRIDE = 0
) (
input logic [WIDTH-1:0] din,
input logic en,
input logic clk,
@ -167,17 +180,20 @@ if (SHORT == 1) begin : genblock
if (1) begin : genblock
assign dout = din;
end
end
else begin : genblock
end else begin : genblock
rvclkhdr clkhdr (.*);
rvdff #(WIDTH) dff (.*, .clk(l1clk));
rvdff #(WIDTH) dff (
.*,
.clk(l1clk)
);
end // else: !if(SHORT == 1)
endmodule // rvdffe
module rvdffpcie #( parameter WIDTH=31 )
(
module rvdffpcie #(
parameter WIDTH = 31
) (
input logic [WIDTH-1:0] din,
input logic clk,
input logic rst_l,
@ -186,15 +202,22 @@ module rvdffpcie #( parameter WIDTH=31 )
output logic [WIDTH-1:0] dout
);
rvdfflie #(.WIDTH(WIDTH), .LEFT(19)) dff (.*);
rvdfflie #(
.WIDTH(WIDTH),
.LEFT (19)
) dff (
.*
);
endmodule
// format: { LEFT, EXTRA }
// LEFT # of bits will be done with rvdffie, all else EXTRA with rvdffe
module rvdfflie #( parameter WIDTH=16, LEFT=8 )
(
module rvdfflie #(
parameter WIDTH = 16,
LEFT = 8
) (
input logic [WIDTH-1:0] din,
input logic clk,
input logic rst_l,
@ -210,8 +233,16 @@ module rvdfflie #( parameter WIDTH=16, LEFT=8 )
localparam XMSB = LLSB - 1;
localparam XLSB = LLSB - EXTRA;
rvdffiee #(LEFT) dff_left (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB]));
rvdffe #(EXTRA) dff_extra (.*, .din(din[XMSB:XLSB]), .dout(dout[XMSB:XLSB]));
rvdffiee #(LEFT) dff_left (
.*,
.din (din[LMSB:LLSB]),
.dout(dout[LMSB:LLSB])
);
rvdffe #(EXTRA) dff_extra (
.*,
.din (din[XMSB:XLSB]),
.dout(dout[XMSB:XLSB])
);
endmodule
@ -221,8 +252,9 @@ endmodule
// special power flop for predict packet
// format: { LEFT, RIGHT==31 }
// LEFT # of bits will be done with rvdffe; RIGHT is enabled by LEFT[LSB] & en
module rvdffppe #( parameter WIDTH=32 )
(
module rvdffppe #(
parameter WIDTH = 32
) (
input logic [WIDTH-1:0] din,
input logic clk,
input logic rst_l,
@ -239,16 +271,27 @@ module rvdffppe #( parameter WIDTH=32 )
localparam RMSB = LLSB - 1;
localparam RLSB = LLSB - RIGHT;
rvdffe #(LEFT) dff_left (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB]));
rvdffe #(RIGHT) dff_right (.*, .din(din[RMSB:RLSB]), .dout(dout[RMSB:RLSB]), .en(en & din[LLSB])); // qualify with pret
rvdffe #(LEFT) dff_left (
.*,
.din (din[LMSB:LLSB]),
.dout(dout[LMSB:LLSB])
);
rvdffe #(RIGHT) dff_right (
.*,
.din (din[RMSB:RLSB]),
.dout(dout[RMSB:RLSB]),
.en (en & din[LLSB])
); // qualify with pret
endmodule
module rvdffie #( parameter WIDTH=1, OVERRIDE=0 )
(
module rvdffie #(
parameter WIDTH = 1,
OVERRIDE = 0
) (
input logic [WIDTH-1:0] din,
input logic clk,
@ -263,13 +306,18 @@ module rvdffie #( parameter WIDTH=1, OVERRIDE=0 )
assign en = |(din ^ dout);
rvclkhdr clkhdr (.*);
rvdff #(WIDTH) dff (.*, .clk(l1clk));
rvdff #(WIDTH) dff (
.*,
.clk(l1clk)
);
endmodule
// ie flop but it has an .en input
module rvdffiee #( parameter WIDTH=1, OVERRIDE=0 )
(
module rvdffiee #(
parameter WIDTH = 1,
OVERRIDE = 0
) (
input logic [WIDTH-1:0] din,
input logic clk,
@ -285,14 +333,18 @@ module rvdffiee #( parameter WIDTH=1, OVERRIDE=0 )
assign final_en = (|(din ^ dout)) & en;
rvdffe #(WIDTH) dff (.*, .en(final_en));
rvdffe #(WIDTH) dff (
.*,
.en(final_en)
);
endmodule
module rvsyncss #(parameter WIDTH = 251)
(
module rvsyncss #(
parameter WIDTH = 251
) (
input logic clk,
input logic rst_l,
input logic [WIDTH-1:0] din,
@ -301,13 +353,22 @@ module rvsyncss #(parameter WIDTH = 251)
logic [WIDTH-1:0] din_ff1;
rvdff #(WIDTH) sync_ff1 (.*, .din (din[WIDTH-1:0]), .dout(din_ff1[WIDTH-1:0]));
rvdff #(WIDTH) sync_ff2 (.*, .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0]));
rvdff #(WIDTH) sync_ff1 (
.*,
.din (din[WIDTH-1:0]),
.dout(din_ff1[WIDTH-1:0])
);
rvdff #(WIDTH) sync_ff2 (
.*,
.din (din_ff1[WIDTH-1:0]),
.dout(dout[WIDTH-1:0])
);
endmodule // rvsyncss
module rvsyncss_fpga #(parameter WIDTH = 251)
(
module rvsyncss_fpga #(
parameter WIDTH = 251
) (
input logic gw_clk,
input logic rawclk,
input logic clken,
@ -318,13 +379,26 @@ module rvsyncss_fpga #(parameter WIDTH = 251)
logic [WIDTH-1:0] din_ff1;
rvdff_fpga #(WIDTH) sync_ff1 (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din[WIDTH-1:0]), .dout(din_ff1[WIDTH-1:0]));
rvdff_fpga #(WIDTH) sync_ff2 (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0]));
rvdff_fpga #(WIDTH) sync_ff1 (
.*,
.clk(gw_clk),
.rawclk(rawclk),
.clken(clken),
.din(din[WIDTH-1:0]),
.dout(din_ff1[WIDTH-1:0])
);
rvdff_fpga #(WIDTH) sync_ff2 (
.*,
.clk(gw_clk),
.rawclk(rawclk),
.clken(clken),
.din(din_ff1[WIDTH-1:0]),
.dout(dout[WIDTH-1:0])
);
endmodule // rvsyncss
module rvlsadder
(
module rvlsadder (
input logic [31:0] rs1,
input logic [11:0] offset,
@ -353,8 +427,7 @@ endmodule // rvlsadder
// assume we only maintain pc[31:1] in the pipe
module rvbradder
(
module rvbradder (
input [31:1] pc,
input [12:1] offset,
@ -385,8 +458,9 @@ endmodule // rvbradder
// 2s complement circuit
module rvtwoscomp #( parameter WIDTH=32 )
(
module rvtwoscomp #(
parameter WIDTH = 32
) (
input logic [WIDTH-1:0] din,
output logic [WIDTH-1:0] dout
@ -405,8 +479,10 @@ module rvtwoscomp #( parameter WIDTH=32 )
endmodule // 2'scomp
// find first
module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) )
(
module rvfindfirst1 #(
parameter WIDTH = 32,
SHIFT = $clog2(WIDTH)
) (
input logic [WIDTH-1:0] din,
output logic [SHIFT-1:0] dout
@ -424,8 +500,9 @@ module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) )
end
endmodule // rvfindfirst1
module rvfindfirst1hot #( parameter WIDTH=32 )
(
module rvfindfirst1hot #(
parameter WIDTH = 32
) (
input logic [WIDTH-1:0] din,
output logic [WIDTH-1:0] dout
@ -444,8 +521,9 @@ endmodule // rvfindfirst1hot
// mask and match function matches bits after finding the first 0 position
// find first starting from LSB. Skip that location and match the rest of the bits
module rvmaskandmatch #( parameter WIDTH=32 )
(
module rvmaskandmatch #(
parameter WIDTH = 32
) (
input logic [WIDTH-1:0] mask, // this will have the mask in the lower bit positions
input logic [WIDTH-1:0] data, // this is what needs to be matched on the upper bits with the mask's upper bits
input logic masken, // when 1 : do mask. 0 : full match
@ -472,8 +550,10 @@ endmodule // rvmaskandmatch
// Check if the S_ADDR <= addr < E_ADDR
module rvrangecheck #(CCM_SADR = 32'h0,
CCM_SIZE = 128) (
module rvrangecheck #(
CCM_SADR = 32'h0,
CCM_SIZE = 128
) (
input logic [31:0] addr, // Address to be checked for range
output logic in_range, // S_ADDR <= start_addr < E_ADDR
output logic in_region
@ -491,13 +571,14 @@ module rvrangecheck #(CCM_SADR = 32'h0,
assign in_region = (addr[31:(32-REGION_BITS)] == region[REGION_BITS-1:0]);
if (CCM_SIZE == 48)
assign in_range = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]) & ~(&addr[MASK_BITS-1 : MASK_BITS-2]);
else
assign in_range = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]);
else assign in_range = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]);
endmodule // rvrangechecker
// 16 bit even parity generator
module rveven_paritygen #(WIDTH = 16) (
module rveven_paritygen #(
WIDTH = 16
) (
input logic [WIDTH-1:0] data_in, // Data
output logic parity_out // generated even parity
);
@ -506,7 +587,9 @@ module rveven_paritygen #(WIDTH = 16) (
endmodule // rveven_paritygen
module rveven_paritycheck #(WIDTH = 16) (
module rveven_paritycheck #(
WIDTH = 16
) (
input logic [WIDTH-1:0] data_in, // Data
input logic parity_in,
output logic parity_err // Parity error
@ -569,11 +652,36 @@ module rvecc_decode (
end
// Generate the corrected data
assign din_plus_parity[38:0] = {ecc_in[6], din[31:26], ecc_in[5], din[25:11], ecc_in[4], din[10:4], ecc_in[3], din[3:1], ecc_in[2], din[0], ecc_in[1:0]};
assign din_plus_parity[38:0] = {
ecc_in[6],
din[31:26],
ecc_in[5],
din[25:11],
ecc_in[4],
din[10:4],
ecc_in[3],
din[3:1],
ecc_in[2],
din[0],
ecc_in[1:0]
};
assign dout_plus_parity[38:0] = single_ecc_error ? (error_mask[38:0] ^ din_plus_parity[38:0]) : din_plus_parity[38:0];
assign dout[31:0] = {dout_plus_parity[37:32], dout_plus_parity[30:16], dout_plus_parity[14:8], dout_plus_parity[6:4], dout_plus_parity[2]};
assign ecc_out[6:0] = {(dout_plus_parity[38] ^ (ecc_check[6:0] == 7'b1000000)), dout_plus_parity[31], dout_plus_parity[15], dout_plus_parity[7], dout_plus_parity[3], dout_plus_parity[1:0]};
assign dout[31:0] = {
dout_plus_parity[37:32],
dout_plus_parity[30:16],
dout_plus_parity[14:8],
dout_plus_parity[6:4],
dout_plus_parity[2]
};
assign ecc_out[6:0] = {
(dout_plus_parity[38] ^ (ecc_check[6:0] == 7'b1000000)),
dout_plus_parity[31],
dout_plus_parity[15],
dout_plus_parity[7],
dout_plus_parity[3],
dout_plus_parity[1:0]
};
endmodule // rvecc_decode
@ -627,9 +735,10 @@ module rvecc_decode_64 (
endmodule // rvecc_decode_64
module clockhdr
(
input logic SE, EN, CK,
module clockhdr (
input logic SE,
EN,
CK,
output Q
);
@ -644,16 +753,14 @@ module clockhdr
end
`else
always @(CK, enable) begin
if(!CK)
en_ff = enable;
if (!CK) en_ff = enable;
end
`endif
assign Q = CK & en_ff;
endmodule
module rvclkhdr
(
module rvclkhdr (
input logic en,
input logic clk,
input logic scan_mode,
@ -663,12 +770,16 @@ module rvclkhdr
logic SE;
assign SE = 0;
clockhdr clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
clockhdr clkhdr (
.*,
.EN(en),
.CK(clk),
.Q (l1clk)
);
endmodule // rvclkhdr
module rvoclkhdr
(
module rvoclkhdr (
input logic en,
input logic clk,
input logic scan_mode,
@ -678,7 +789,12 @@ module rvoclkhdr
logic SE;
assign SE = 0;
clockhdr clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
clockhdr clkhdr (
.*,
.EN(en),
.CK(clk),
.Q (l1clk)
);
endmodule

View File

@ -5,9 +5,11 @@ module el2_btb_tag_hash #(
output logic [pt.BTB_BTAG_SIZE-1:0] hash
);
assign hash = {(pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+1] ^
assign hash = {
(pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+1] ^
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+1] ^
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1])};
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1])
};
endmodule
module el2_btb_tag_hash_fold #(
@ -17,9 +19,11 @@ module el2_btb_tag_hash_fold #(
output logic [pt.BTB_BTAG_SIZE-1:0] hash
);
assign hash = {(
assign hash = {
(
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+1] ^
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1])};
pc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1])
};
endmodule
@ -34,8 +38,7 @@ module el2_btb_addr_hash #(
if (pt.BTB_FOLD2_INDEX_HASH) begin : fold2
assign hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = pc[pt.BTB_INDEX1_HI:pt.BTB_INDEX1_LO] ^
pc[pt.BTB_INDEX3_HI:pt.BTB_INDEX3_LO];
end
else begin
end else begin
assign hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = pc[pt.BTB_INDEX1_HI:pt.BTB_INDEX1_LO] ^
pc[pt.BTB_INDEX2_HI:pt.BTB_INDEX2_LO] ^
pc[pt.BTB_INDEX3_HI:pt.BTB_INDEX3_LO];
@ -54,10 +57,14 @@ module el2_btb_ghr_hash #(
// The hash function is too complex to write in verilog for all cases.
// The config script generates the logic string based on the bp config.
if (pt.BHT_GHR_HASH_1) begin : ghrhash_cfg1
assign hash[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = { ghr[pt.BHT_GHR_SIZE-1:pt.BTB_INDEX1_HI-1], hashin[pt.BTB_INDEX1_HI:2]^ghr[pt.BTB_INDEX1_HI-2:0]};
end
else begin : ghrhash_cfg2
assign hash[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = { hashin[pt.BHT_GHR_SIZE+1:2]^ghr[pt.BHT_GHR_SIZE-1:0]};
assign hash[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = {
ghr[pt.BHT_GHR_SIZE-1:pt.BTB_INDEX1_HI-1],
hashin[pt.BTB_INDEX1_HI:2] ^ ghr[pt.BTB_INDEX1_HI-2:0]
};
end else begin : ghrhash_cfg2
assign hash[pt.BHT_ADDR_HI:pt.BHT_ADDR_LO] = {
hashin[pt.BHT_GHR_SIZE+1:2] ^ ghr[pt.BHT_GHR_SIZE-1:0]
};
end

View File

@ -83,7 +83,10 @@ assign ROP = ME; \
endmodule
// parameterizable RAM for verilator sims
module el2_ram #(depth=4096, width=39) (
module el2_ram #(
depth = 4096,
width = 39
) (
input logic [$clog2(depth)-1:0] ADR,
input logic [(width-1):0] D,
output logic [(width-1):0] Q,
@ -95,7 +98,10 @@ always @(posedge CLK) begin
`ifdef GTLSIM
if (ME && WE) ram_core[ADR] <= D;
`else
if (ME && WE) begin ram_core[ADR] <= D; Q <= 'x; end
if (ME && WE) begin
ram_core[ADR] <= D;
Q <= 'x;
end
`endif
if (ME && ~WE) Q <= ram_core[ADR];
end

View File

@ -29,8 +29,7 @@ module el2_lsu
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk_override, // Override non-functional clock gating
input logic dec_tlu_flush_lower_r, // I0/I1 writeback flush. This is used to flush the old packets only
@ -330,7 +329,9 @@ import el2_pkg::*;
assign lsu_pmu_load_external_m = lsu_pkt_m.valid & lsu_pkt_m.load & addr_external_m;
assign lsu_pmu_store_external_m = lsu_pkt_m.valid & lsu_pkt_m.store & addr_external_m;
el2_lsu_dccm_ctl #(.pt(pt)) dccm_ctl (
el2_lsu_dccm_ctl #(
.pt(pt)
) dccm_ctl (
.lsu_addr_d(lsu_addr_d[31:0]),
.end_addr_d(end_addr_d[pt.DCCM_BITS-1:0]),
.lsu_addr_m(lsu_addr_m[pt.DCCM_BITS-1:0]),
@ -341,7 +342,9 @@ import el2_pkg::*;
.*
);
el2_lsu_stbuf #(.pt(pt)) stbuf (
el2_lsu_stbuf #(
.pt(pt)
) stbuf (
.lsu_addr_d(lsu_addr_d[pt.LSU_SB_BITS-1:0]),
.end_addr_d(end_addr_d[pt.LSU_SB_BITS-1:0]),
@ -349,7 +352,9 @@ import el2_pkg::*;
);
el2_lsu_ecc #(.pt(pt)) ecc (
el2_lsu_ecc #(
.pt(pt)
) ecc (
.lsu_addr_r(lsu_addr_r[pt.DCCM_BITS-1:0]),
.end_addr_r(end_addr_r[pt.DCCM_BITS-1:0]),
.lsu_addr_m(lsu_addr_m[pt.DCCM_BITS-1:0]),
@ -357,7 +362,9 @@ import el2_pkg::*;
.*
);
el2_lsu_trigger #(.pt(pt)) trigger (
el2_lsu_trigger #(
.pt(pt)
) trigger (
.store_data_m(store_data_m[31:0]),
.*
);
@ -366,7 +373,9 @@ import el2_pkg::*;
el2_lsu_clkdomain #(.pt(pt)) clkdomain (.*);
// Bus interface
el2_lsu_bus_intf #(.pt(pt)) bus_intf (
el2_lsu_bus_intf #(
.pt(pt)
) bus_intf (
.lsu_addr_m(lsu_addr_m[31:0] & {32{addr_external_m & lsu_pkt_m.valid}}),
.lsu_addr_r(lsu_addr_r[31:0] & {32{lsu_busreq_r}}),
@ -378,7 +387,17 @@ import el2_pkg::*;
);
//Flops
rvdff #(3) dma_mem_tag_mff (.*, .din(dma_mem_tag_d[2:0]), .dout(dma_mem_tag_m[2:0]), .clk(lsu_c1_m_clk));
rvdff #(2) lsu_raw_fwd_r_ff (.*, .din({lsu_raw_fwd_hi_m, lsu_raw_fwd_lo_m}), .dout({lsu_raw_fwd_hi_r, lsu_raw_fwd_lo_r}), .clk(lsu_c2_r_clk));
rvdff #(3) dma_mem_tag_mff (
.*,
.din (dma_mem_tag_d[2:0]),
.dout(dma_mem_tag_m[2:0]),
.clk (lsu_c1_m_clk)
);
rvdff #(2) lsu_raw_fwd_r_ff (
.*,
.din ({lsu_raw_fwd_hi_m, lsu_raw_fwd_lo_m}),
.dout({lsu_raw_fwd_hi_r, lsu_raw_fwd_lo_r}),
.clk (lsu_c2_r_clk)
);
endmodule // el2_lsu

View File

@ -71,16 +71,20 @@ import el2_pkg::*;
if (pt.DCCM_ENABLE == 1) begin : Gen_dccm_enable
// Start address check
rvrangecheck #(.CCM_SADR(pt.DCCM_SADR),
.CCM_SIZE(pt.DCCM_SIZE)) start_addr_dccm_rangecheck (
rvrangecheck #(
.CCM_SADR(pt.DCCM_SADR),
.CCM_SIZE(pt.DCCM_SIZE)
) start_addr_dccm_rangecheck (
.addr(start_addr_d[31:0]),
.in_range(start_addr_in_dccm_d),
.in_region(start_addr_in_dccm_region_d)
);
// End address check
rvrangecheck #(.CCM_SADR(pt.DCCM_SADR),
.CCM_SIZE(pt.DCCM_SIZE)) end_addr_dccm_rangecheck (
rvrangecheck #(
.CCM_SADR(pt.DCCM_SADR),
.CCM_SIZE(pt.DCCM_SIZE)
) end_addr_dccm_rangecheck (
.addr(end_addr_d[31:0]),
.in_range(end_addr_in_dccm_d),
.in_region(end_addr_in_dccm_region_d)
@ -100,16 +104,20 @@ import el2_pkg::*;
// PIC memory check
// Start address check
rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR),
.CCM_SIZE(pt.PIC_SIZE)) start_addr_pic_rangecheck (
rvrangecheck #(
.CCM_SADR(pt.PIC_BASE_ADDR),
.CCM_SIZE(pt.PIC_SIZE)
) start_addr_pic_rangecheck (
.addr(start_addr_d[31:0]),
.in_range(start_addr_in_pic_d),
.in_region(start_addr_in_pic_region_d)
);
// End address check
rvrangecheck #(.CCM_SADR(pt.PIC_BASE_ADDR),
.CCM_SIZE(pt.PIC_SIZE)) end_addr_pic_rangecheck (
rvrangecheck #(
.CCM_SADR(pt.PIC_BASE_ADDR),
.CCM_SIZE(pt.PIC_SIZE)
) end_addr_pic_rangecheck (
.addr(end_addr_d[31:0]),
.in_range(end_addr_in_pic_d),
.in_region(end_addr_in_pic_region_d)
@ -186,6 +194,13 @@ import el2_pkg::*;
(end_addr_in_dccm_region_d & ~end_addr_in_dccm_d)) & lsu_pkt_d.valid & lsu_pkt_d.fast_int;
assign fir_nondccm_access_error_d = ~(start_addr_in_dccm_region_d & end_addr_in_dccm_region_d) & lsu_pkt_d.valid & lsu_pkt_d.fast_int;
rvdff #(.WIDTH(1)) is_sideeffects_mff (.din(is_sideeffects_d), .dout(is_sideeffects_m), .clk(lsu_c2_m_clk), .*);
rvdff #(
.WIDTH(1)
) is_sideeffects_mff (
.din (is_sideeffects_d),
.dout(is_sideeffects_m),
.clk (lsu_c2_m_clk),
.*
);
endmodule // el2_lsu_addrcheck

View File

@ -77,8 +77,10 @@ import el2_pkg::*;
output logic lsu_bus_buffer_full_any, // bus buffer is full
output logic lsu_bus_buffer_empty_any, // bus buffer is empty
output logic [3:0] ld_byte_hit_buf_lo, ld_byte_hit_buf_hi, // Byte enables for forwarding data
output logic [31:0] ld_fwddata_buf_lo, ld_fwddata_buf_hi, // load forwarding data
output logic [ 3:0] ld_byte_hit_buf_lo,
ld_byte_hit_buf_hi, // Byte enables for forwarding data
output logic [31:0] ld_fwddata_buf_lo,
ld_fwddata_buf_hi, // load forwarding data
output logic lsu_imprecise_error_load_any, // imprecise load bus error
output logic lsu_imprecise_error_store_any, // imprecise store bus error
@ -152,7 +154,15 @@ import el2_pkg::*;
// For Ld: IDLE -> WAIT -> CMD -> RESP -> DONE_PARTIAL(?) -> DONE_WAIT(?) -> DONE -> IDLE
// For St: IDLE -> WAIT -> CMD -> RESP(?) -> IDLE
typedef enum logic [2:0] {IDLE=3'b000, WAIT=3'b001, CMD=3'b010, RESP=3'b011, DONE_PARTIAL=3'b100, DONE_WAIT=3'b101, DONE=3'b110} state_t;
typedef enum logic [2:0] {
IDLE = 3'b000,
WAIT = 3'b001,
CMD = 3'b010,
RESP = 3'b011,
DONE_PARTIAL = 3'b100,
DONE_WAIT = 3'b101,
DONE = 3'b110
} state_t;
localparam DEPTH = pt.LSU_NUM_NBLOAD;
localparam DEPTH_LOG2 = pt.LSU_NUM_NBLOAD_WIDTH;
@ -446,20 +456,130 @@ import el2_pkg::*;
ibuf_data[(8*i)+7:(8*i)];
end
rvdffsc #(.WIDTH(1)) ibuf_valid_ff (.din(1'b1), .dout(ibuf_valid), .en(ibuf_wr_en), .clear(ibuf_rst), .clk(lsu_free_c2_clk), .*);
rvdffs #(.WIDTH(DEPTH_LOG2)) ibuf_tagff (.din(ibuf_tag_in), .dout(ibuf_tag), .en(ibuf_wr_en), .clk(lsu_bus_ibuf_c1_clk), .*);
rvdffs #(.WIDTH(DEPTH_LOG2)) ibuf_dualtagff (.din(ibuf_dualtag_in), .dout(ibuf_dualtag), .en(ibuf_wr_en), .clk(lsu_bus_ibuf_c1_clk), .*);
rvdffs #(.WIDTH(1)) ibuf_dualff (.din(ldst_dual_r), .dout(ibuf_dual), .en(ibuf_wr_en), .clk(lsu_bus_ibuf_c1_clk), .*);
rvdffs #(.WIDTH(1)) ibuf_samedwff (.din(ldst_samedw_r), .dout(ibuf_samedw), .en(ibuf_wr_en), .clk(lsu_bus_ibuf_c1_clk), .*);
rvdffs #(.WIDTH(1)) ibuf_nomergeff (.din(no_dword_merge_r), .dout(ibuf_nomerge), .en(ibuf_wr_en), .clk(lsu_bus_ibuf_c1_clk), .*);
rvdffs #(.WIDTH(1)) ibuf_sideeffectff (.din(is_sideeffects_r), .dout(ibuf_sideeffect), .en(ibuf_wr_en), .clk(lsu_bus_ibuf_c1_clk), .*);
rvdffs #(.WIDTH(1)) ibuf_unsignff (.din(lsu_pkt_r.unsign), .dout(ibuf_unsign), .en(ibuf_wr_en), .clk(lsu_bus_ibuf_c1_clk), .*);
rvdffs #(.WIDTH(1)) ibuf_writeff (.din(lsu_pkt_r.store), .dout(ibuf_write), .en(ibuf_wr_en), .clk(lsu_bus_ibuf_c1_clk), .*);
rvdffs #(.WIDTH(2)) ibuf_szff (.din(ibuf_sz_in[1:0]), .dout(ibuf_sz), .en(ibuf_wr_en), .clk(lsu_bus_ibuf_c1_clk), .*);
rvdffe #(.WIDTH(32)) ibuf_addrff (.din(ibuf_addr_in[31:0]), .dout(ibuf_addr), .en(ibuf_wr_en), .*);
rvdffs #(.WIDTH(4)) ibuf_byteenff (.din(ibuf_byteen_in[3:0]), .dout(ibuf_byteen), .en(ibuf_wr_en), .clk(lsu_bus_ibuf_c1_clk), .*);
rvdffe #(.WIDTH(32)) ibuf_dataff (.din(ibuf_data_in[31:0]), .dout(ibuf_data), .en(ibuf_wr_en), .*);
rvdff #(.WIDTH(TIMER_LOG2)) ibuf_timerff (.din(ibuf_timer_in), .dout(ibuf_timer), .clk(lsu_free_c2_clk), .*);
rvdffsc #(
.WIDTH(1)
) ibuf_valid_ff (
.din(1'b1),
.dout(ibuf_valid),
.en(ibuf_wr_en),
.clear(ibuf_rst),
.clk(lsu_free_c2_clk),
.*
);
rvdffs #(
.WIDTH(DEPTH_LOG2)
) ibuf_tagff (
.din (ibuf_tag_in),
.dout(ibuf_tag),
.en (ibuf_wr_en),
.clk (lsu_bus_ibuf_c1_clk),
.*
);
rvdffs #(
.WIDTH(DEPTH_LOG2)
) ibuf_dualtagff (
.din (ibuf_dualtag_in),
.dout(ibuf_dualtag),
.en (ibuf_wr_en),
.clk (lsu_bus_ibuf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) ibuf_dualff (
.din (ldst_dual_r),
.dout(ibuf_dual),
.en (ibuf_wr_en),
.clk (lsu_bus_ibuf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) ibuf_samedwff (
.din (ldst_samedw_r),
.dout(ibuf_samedw),
.en (ibuf_wr_en),
.clk (lsu_bus_ibuf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) ibuf_nomergeff (
.din (no_dword_merge_r),
.dout(ibuf_nomerge),
.en (ibuf_wr_en),
.clk (lsu_bus_ibuf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) ibuf_sideeffectff (
.din (is_sideeffects_r),
.dout(ibuf_sideeffect),
.en (ibuf_wr_en),
.clk (lsu_bus_ibuf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) ibuf_unsignff (
.din (lsu_pkt_r.unsign),
.dout(ibuf_unsign),
.en (ibuf_wr_en),
.clk (lsu_bus_ibuf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) ibuf_writeff (
.din (lsu_pkt_r.store),
.dout(ibuf_write),
.en (ibuf_wr_en),
.clk (lsu_bus_ibuf_c1_clk),
.*
);
rvdffs #(
.WIDTH(2)
) ibuf_szff (
.din (ibuf_sz_in[1:0]),
.dout(ibuf_sz),
.en (ibuf_wr_en),
.clk (lsu_bus_ibuf_c1_clk),
.*
);
rvdffe #(
.WIDTH(32)
) ibuf_addrff (
.din (ibuf_addr_in[31:0]),
.dout(ibuf_addr),
.en (ibuf_wr_en),
.*
);
rvdffs #(
.WIDTH(4)
) ibuf_byteenff (
.din (ibuf_byteen_in[3:0]),
.dout(ibuf_byteen),
.en (ibuf_wr_en),
.clk (lsu_bus_ibuf_c1_clk),
.*
);
rvdffe #(
.WIDTH(32)
) ibuf_dataff (
.din (ibuf_data_in[31:0]),
.dout(ibuf_data),
.en (ibuf_wr_en),
.*
);
rvdff #(
.WIDTH(TIMER_LOG2)
) ibuf_timerff (
.din (ibuf_timer_in),
.dout(ibuf_timer),
.clk (lsu_free_c2_clk),
.*
);
//------------------------------------------------------------------------------
@ -527,23 +647,177 @@ import el2_pkg::*;
(ibuf_buf_byp & ldst_samedw_r & ldst_dual_r);
rvdff_fpga #(.WIDTH(1)) obuf_wren_ff (.din(obuf_wr_en), .dout(obuf_wr_enQ), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdffsc #(.WIDTH(1)) obuf_valid_ff (.din(1'b1), .dout(obuf_valid), .en(obuf_wr_en), .clear(obuf_rst), .clk(lsu_free_c2_clk), .*);
rvdffs #(.WIDTH(1)) obuf_nosend_ff (.din(obuf_nosend_in), .dout(obuf_nosend), .en(obuf_wr_en), .clk(lsu_free_c2_clk), .*);
rvdffs #(.WIDTH(1)) obuf_rdrsp_pend_ff(.din(obuf_rdrsp_pend_in), .dout(obuf_rdrsp_pend), .en(obuf_rdrsp_pend_en), .clk(lsu_free_c2_clk), .*);
rvdff_fpga #(.WIDTH(1)) obuf_cmd_done_ff (.din(obuf_cmd_done_in), .dout(obuf_cmd_done), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) obuf_data_done_ff (.din(obuf_data_done_in), .dout(obuf_data_done), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(pt.LSU_BUS_TAG)) obuf_rdrsp_tagff (.din(obuf_rdrsp_tag_in), .dout(obuf_rdrsp_tag), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(pt.LSU_BUS_TAG)) obuf_tag0ff (.din(obuf_tag0_in), .dout(obuf_tag0), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(pt.LSU_BUS_TAG)) obuf_tag1ff (.din(obuf_tag1_in), .dout(obuf_tag1), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(1)) obuf_mergeff (.din(obuf_merge_in), .dout(obuf_merge), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(1)) obuf_writeff (.din(obuf_write_in), .dout(obuf_write), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(1)) obuf_sideeffectff (.din(obuf_sideeffect_in), .dout(obuf_sideeffect), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(2)) obuf_szff (.din(obuf_sz_in[1:0]), .dout(obuf_sz), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
rvdffs_fpga #(.WIDTH(8)) obuf_byteenff (.din(obuf_byteen_in[7:0]), .dout(obuf_byteen), .en(obuf_wr_en), .clk(lsu_bus_obuf_c1_clk), .clken(lsu_bus_obuf_c1_clken), .rawclk(clk), .*);
rvdffe #(.WIDTH(32)) obuf_addrff (.din(obuf_addr_in[31:0]), .dout(obuf_addr), .en(obuf_wr_en), .*);
rvdffe #(.WIDTH(64)) obuf_dataff (.din(obuf_data_in[63:0]), .dout(obuf_data), .en(obuf_wr_en), .*);
rvdff_fpga #(.WIDTH(TIMER_LOG2)) obuf_timerff (.din(obuf_wr_timer_in), .dout(obuf_wr_timer), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(
.WIDTH(1)
) obuf_wren_ff (
.din(obuf_wr_en),
.dout(obuf_wr_enQ),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdffsc #(
.WIDTH(1)
) obuf_valid_ff (
.din(1'b1),
.dout(obuf_valid),
.en(obuf_wr_en),
.clear(obuf_rst),
.clk(lsu_free_c2_clk),
.*
);
rvdffs #(
.WIDTH(1)
) obuf_nosend_ff (
.din (obuf_nosend_in),
.dout(obuf_nosend),
.en (obuf_wr_en),
.clk (lsu_free_c2_clk),
.*
);
rvdffs #(
.WIDTH(1)
) obuf_rdrsp_pend_ff (
.din (obuf_rdrsp_pend_in),
.dout(obuf_rdrsp_pend),
.en (obuf_rdrsp_pend_en),
.clk (lsu_free_c2_clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) obuf_cmd_done_ff (
.din(obuf_cmd_done_in),
.dout(obuf_cmd_done),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) obuf_data_done_ff (
.din(obuf_data_done_in),
.dout(obuf_data_done),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(pt.LSU_BUS_TAG)
) obuf_rdrsp_tagff (
.din(obuf_rdrsp_tag_in),
.dout(obuf_rdrsp_tag),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(pt.LSU_BUS_TAG)
) obuf_tag0ff (
.din(obuf_tag0_in),
.dout(obuf_tag0),
.en(obuf_wr_en),
.clk(lsu_bus_obuf_c1_clk),
.clken(lsu_bus_obuf_c1_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(pt.LSU_BUS_TAG)
) obuf_tag1ff (
.din(obuf_tag1_in),
.dout(obuf_tag1),
.en(obuf_wr_en),
.clk(lsu_bus_obuf_c1_clk),
.clken(lsu_bus_obuf_c1_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(1)
) obuf_mergeff (
.din(obuf_merge_in),
.dout(obuf_merge),
.en(obuf_wr_en),
.clk(lsu_bus_obuf_c1_clk),
.clken(lsu_bus_obuf_c1_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(1)
) obuf_writeff (
.din(obuf_write_in),
.dout(obuf_write),
.en(obuf_wr_en),
.clk(lsu_bus_obuf_c1_clk),
.clken(lsu_bus_obuf_c1_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(1)
) obuf_sideeffectff (
.din(obuf_sideeffect_in),
.dout(obuf_sideeffect),
.en(obuf_wr_en),
.clk(lsu_bus_obuf_c1_clk),
.clken(lsu_bus_obuf_c1_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(2)
) obuf_szff (
.din(obuf_sz_in[1:0]),
.dout(obuf_sz),
.en(obuf_wr_en),
.clk(lsu_bus_obuf_c1_clk),
.clken(lsu_bus_obuf_c1_clken),
.rawclk(clk),
.*
);
rvdffs_fpga #(
.WIDTH(8)
) obuf_byteenff (
.din(obuf_byteen_in[7:0]),
.dout(obuf_byteen),
.en(obuf_wr_en),
.clk(lsu_bus_obuf_c1_clk),
.clken(lsu_bus_obuf_c1_clken),
.rawclk(clk),
.*
);
rvdffe #(
.WIDTH(32)
) obuf_addrff (
.din (obuf_addr_in[31:0]),
.dout(obuf_addr),
.en (obuf_wr_en),
.*
);
rvdffe #(
.WIDTH(64)
) obuf_dataff (
.din (obuf_data_in[63:0]),
.dout(obuf_data),
.en (obuf_wr_en),
.*
);
rvdff_fpga #(
.WIDTH(TIMER_LOG2)
) obuf_timerff (
.din(obuf_wr_timer_in),
.dout(obuf_wr_timer),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
//------------------------------------------------------------------------------
@ -735,24 +1009,165 @@ import el2_pkg::*;
endcase
end
rvdffs #(.WIDTH($bits(state_t))) buf_state_ff (.din(buf_nxtstate[i]), .dout({buf_state[i]}), .en(buf_state_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdff #(.WIDTH(DEPTH)) buf_ageff (.din(buf_age_in[i]), .dout(buf_ageQ[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdff #(.WIDTH(DEPTH)) buf_rspageff (.din(buf_rspage_in[i]), .dout(buf_rspageQ[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(.WIDTH(DEPTH_LOG2)) buf_dualtagff (.din(buf_dualtag_in[i]), .dout(buf_dualtag[i]), .en(buf_wr_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(.WIDTH(1)) buf_dualff (.din(buf_dual_in[i]), .dout(buf_dual[i]), .en(buf_wr_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(.WIDTH(1)) buf_samedwff (.din(buf_samedw_in[i]), .dout(buf_samedw[i]), .en(buf_wr_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(.WIDTH(1)) buf_nomergeff (.din(buf_nomerge_in[i]), .dout(buf_nomerge[i]), .en(buf_wr_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(.WIDTH(1)) buf_dualhiff (.din(buf_dualhi_in[i]), .dout(buf_dualhi[i]), .en(buf_wr_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(.WIDTH(1)) buf_ldfwdff (.din(buf_ldfwd_in[i]), .dout(buf_ldfwd[i]), .en(buf_ldfwd_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(.WIDTH(DEPTH_LOG2)) buf_ldfwdtagff (.din(buf_ldfwdtag_in[i]), .dout(buf_ldfwdtag[i]), .en(buf_ldfwd_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(.WIDTH(1)) buf_sideeffectff (.din(buf_sideeffect_in[i]), .dout(buf_sideeffect[i]), .en(buf_wr_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(.WIDTH(1)) buf_unsignff (.din(buf_unsign_in[i]), .dout(buf_unsign[i]), .en(buf_wr_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(.WIDTH(1)) buf_writeff (.din(buf_write_in[i]), .dout(buf_write[i]), .en(buf_wr_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(.WIDTH(2)) buf_szff (.din(buf_sz_in[i]), .dout(buf_sz[i]), .en(buf_wr_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffe #(.WIDTH(32)) buf_addrff (.din(buf_addr_in[i][31:0]), .dout(buf_addr[i]), .en(buf_wr_en[i]), .*);
rvdffs #(.WIDTH(4)) buf_byteenff (.din(buf_byteen_in[i][3:0]), .dout(buf_byteen[i]), .en(buf_wr_en[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffe #(.WIDTH(32)) buf_dataff (.din(buf_data_in[i][31:0]), .dout(buf_data[i]), .en(buf_data_en[i]), .*);
rvdffsc #(.WIDTH(1)) buf_errorff (.din(1'b1), .dout(buf_error[i]), .en(buf_error_en[i]), .clear(buf_rst[i]), .clk(lsu_bus_buf_c1_clk), .*);
rvdffs #(
.WIDTH($bits(state_t))
) buf_state_ff (
.din (buf_nxtstate[i]),
.dout({buf_state[i]}),
.en (buf_state_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdff #(
.WIDTH(DEPTH)
) buf_ageff (
.din (buf_age_in[i]),
.dout(buf_ageQ[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdff #(
.WIDTH(DEPTH)
) buf_rspageff (
.din (buf_rspage_in[i]),
.dout(buf_rspageQ[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffs #(
.WIDTH(DEPTH_LOG2)
) buf_dualtagff (
.din (buf_dualtag_in[i]),
.dout(buf_dualtag[i]),
.en (buf_wr_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) buf_dualff (
.din (buf_dual_in[i]),
.dout(buf_dual[i]),
.en (buf_wr_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) buf_samedwff (
.din (buf_samedw_in[i]),
.dout(buf_samedw[i]),
.en (buf_wr_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) buf_nomergeff (
.din (buf_nomerge_in[i]),
.dout(buf_nomerge[i]),
.en (buf_wr_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) buf_dualhiff (
.din (buf_dualhi_in[i]),
.dout(buf_dualhi[i]),
.en (buf_wr_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) buf_ldfwdff (
.din (buf_ldfwd_in[i]),
.dout(buf_ldfwd[i]),
.en (buf_ldfwd_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffs #(
.WIDTH(DEPTH_LOG2)
) buf_ldfwdtagff (
.din (buf_ldfwdtag_in[i]),
.dout(buf_ldfwdtag[i]),
.en (buf_ldfwd_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) buf_sideeffectff (
.din (buf_sideeffect_in[i]),
.dout(buf_sideeffect[i]),
.en (buf_wr_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) buf_unsignff (
.din (buf_unsign_in[i]),
.dout(buf_unsign[i]),
.en (buf_wr_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffs #(
.WIDTH(1)
) buf_writeff (
.din (buf_write_in[i]),
.dout(buf_write[i]),
.en (buf_wr_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffs #(
.WIDTH(2)
) buf_szff (
.din (buf_sz_in[i]),
.dout(buf_sz[i]),
.en (buf_wr_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffe #(
.WIDTH(32)
) buf_addrff (
.din (buf_addr_in[i][31:0]),
.dout(buf_addr[i]),
.en (buf_wr_en[i]),
.*
);
rvdffs #(
.WIDTH(4)
) buf_byteenff (
.din (buf_byteen_in[i][3:0]),
.dout(buf_byteen[i]),
.en (buf_wr_en[i]),
.clk (lsu_bus_buf_c1_clk),
.*
);
rvdffe #(
.WIDTH(32)
) buf_dataff (
.din (buf_data_in[i][31:0]),
.dout(buf_data[i]),
.en (buf_data_en[i]),
.*
);
rvdffsc #(
.WIDTH(1)
) buf_errorff (
.din(1'b1),
.dout(buf_error[i]),
.en(buf_error_en[i]),
.clear(buf_rst[i]),
.clk(lsu_bus_buf_c1_clk),
.*
);
end
@ -767,9 +1182,13 @@ import el2_pkg::*;
any_done_wait_state = 1'b0;
for (int i = 0; i < DEPTH; i++) begin
buf_numvld_any[3:0] += {3'b0, (buf_state[i] != IDLE)};
buf_numvld_wrcmd_any[3:0] += {3'b0, (buf_write[i] & (buf_state[i] == CMD) & ~buf_cmd_state_bus_en[i])};
buf_numvld_wrcmd_any[3:0] += {
3'b0, (buf_write[i] & (buf_state[i] == CMD) & ~buf_cmd_state_bus_en[i])
};
buf_numvld_cmd_any[3:0] += {3'b0, ((buf_state[i] == CMD) & ~buf_cmd_state_bus_en[i])};
buf_numvld_pend_any[3:0] += {3'b0, ((buf_state[i] == WAIT) | ((buf_state[i] == CMD) & ~buf_cmd_state_bus_en[i]))};
buf_numvld_pend_any[3:0] += {
3'b0, ((buf_state[i] == WAIT) | ((buf_state[i] == CMD) & ~buf_cmd_state_bus_en[i]))
};
any_done_wait_state |= (buf_state[i] == DONE_WAIT);
end
end
@ -893,28 +1312,189 @@ import el2_pkg::*;
assign lsu_pmu_bus_error = lsu_imprecise_error_load_any | lsu_imprecise_error_store_any;
assign lsu_pmu_bus_busy = (lsu_axi_awvalid & ~lsu_axi_awready) | (lsu_axi_wvalid & ~lsu_axi_wready) | (lsu_axi_arvalid & ~lsu_axi_arready);
rvdff_fpga #(.WIDTH(1)) lsu_axi_awvalid_ff (.din(lsu_axi_awvalid), .dout(lsu_axi_awvalid_q), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) lsu_axi_awready_ff (.din(lsu_axi_awready), .dout(lsu_axi_awready_q), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) lsu_axi_wvalid_ff (.din(lsu_axi_wvalid), .dout(lsu_axi_wvalid_q), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) lsu_axi_wready_ff (.din(lsu_axi_wready), .dout(lsu_axi_wready_q), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) lsu_axi_arvalid_ff (.din(lsu_axi_arvalid), .dout(lsu_axi_arvalid_q), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) lsu_axi_arready_ff (.din(lsu_axi_arready), .dout(lsu_axi_arready_q), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(
.WIDTH(1)
) lsu_axi_awvalid_ff (
.din(lsu_axi_awvalid),
.dout(lsu_axi_awvalid_q),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) lsu_axi_awready_ff (
.din(lsu_axi_awready),
.dout(lsu_axi_awready_q),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) lsu_axi_wvalid_ff (
.din(lsu_axi_wvalid),
.dout(lsu_axi_wvalid_q),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) lsu_axi_wready_ff (
.din(lsu_axi_wready),
.dout(lsu_axi_wready_q),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) lsu_axi_arvalid_ff (
.din(lsu_axi_arvalid),
.dout(lsu_axi_arvalid_q),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) lsu_axi_arready_ff (
.din(lsu_axi_arready),
.dout(lsu_axi_arready_q),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(.WIDTH(1)) lsu_axi_bvalid_ff (.din(lsu_axi_bvalid), .dout(lsu_axi_bvalid_q), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) lsu_axi_bready_ff (.din(lsu_axi_bready), .dout(lsu_axi_bready_q), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(2)) lsu_axi_bresp_ff (.din(lsu_axi_bresp[1:0]), .dout(lsu_axi_bresp_q[1:0]), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(pt.LSU_BUS_TAG)) lsu_axi_bid_ff (.din(lsu_axi_bid[pt.LSU_BUS_TAG-1:0]),.dout(lsu_axi_bid_q[pt.LSU_BUS_TAG-1:0]),.clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdffe #(.WIDTH(64)) lsu_axi_rdata_ff (.din(lsu_axi_rdata[63:0]), .dout(lsu_axi_rdata_q[63:0]), .en((lsu_axi_rvalid | clk_override) & lsu_bus_clk_en), .*);
rvdff_fpga #(
.WIDTH(1)
) lsu_axi_bvalid_ff (
.din(lsu_axi_bvalid),
.dout(lsu_axi_bvalid_q),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) lsu_axi_bready_ff (
.din(lsu_axi_bready),
.dout(lsu_axi_bready_q),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(2)
) lsu_axi_bresp_ff (
.din(lsu_axi_bresp[1:0]),
.dout(lsu_axi_bresp_q[1:0]),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(pt.LSU_BUS_TAG)
) lsu_axi_bid_ff (
.din(lsu_axi_bid[pt.LSU_BUS_TAG-1:0]),
.dout(lsu_axi_bid_q[pt.LSU_BUS_TAG-1:0]),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdffe #(
.WIDTH(64)
) lsu_axi_rdata_ff (
.din (lsu_axi_rdata[63:0]),
.dout(lsu_axi_rdata_q[63:0]),
.en ((lsu_axi_rvalid | clk_override) & lsu_bus_clk_en),
.*
);
rvdff_fpga #(.WIDTH(1)) lsu_axi_rvalid_ff (.din(lsu_axi_rvalid), .dout(lsu_axi_rvalid_q), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(1)) lsu_axi_rready_ff (.din(lsu_axi_rready), .dout(lsu_axi_rready_q), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(2)) lsu_axi_rresp_ff (.din(lsu_axi_rresp[1:0]), .dout(lsu_axi_rresp_q[1:0]), .clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(.WIDTH(pt.LSU_BUS_TAG)) lsu_axi_rid_ff (.din(lsu_axi_rid[pt.LSU_BUS_TAG-1:0]),.dout(lsu_axi_rid_q[pt.LSU_BUS_TAG-1:0]),.clk(lsu_busm_clk), .clken(lsu_busm_clken), .rawclk(clk), .*);
rvdff_fpga #(
.WIDTH(1)
) lsu_axi_rvalid_ff (
.din(lsu_axi_rvalid),
.dout(lsu_axi_rvalid_q),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(1)
) lsu_axi_rready_ff (
.din(lsu_axi_rready),
.dout(lsu_axi_rready_q),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(2)
) lsu_axi_rresp_ff (
.din(lsu_axi_rresp[1:0]),
.dout(lsu_axi_rresp_q[1:0]),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff_fpga #(
.WIDTH(pt.LSU_BUS_TAG)
) lsu_axi_rid_ff (
.din(lsu_axi_rid[pt.LSU_BUS_TAG-1:0]),
.dout(lsu_axi_rid_q[pt.LSU_BUS_TAG-1:0]),
.clk(lsu_busm_clk),
.clken(lsu_busm_clken),
.rawclk(clk),
.*
);
rvdff #(.WIDTH(DEPTH_LOG2)) lsu_WrPtr0_rff (.din(WrPtr0_m), .dout(WrPtr0_r), .clk(lsu_c2_r_clk), .*);
rvdff #(.WIDTH(DEPTH_LOG2)) lsu_WrPtr1_rff (.din(WrPtr1_m), .dout(WrPtr1_r), .clk(lsu_c2_r_clk), .*);
rvdff #(
.WIDTH(DEPTH_LOG2)
) lsu_WrPtr0_rff (
.din (WrPtr0_m),
.dout(WrPtr0_r),
.clk (lsu_c2_r_clk),
.*
);
rvdff #(
.WIDTH(DEPTH_LOG2)
) lsu_WrPtr1_rff (
.din (WrPtr1_m),
.dout(WrPtr1_r),
.clk (lsu_c2_r_clk),
.*
);
rvdff #(.WIDTH(1)) lsu_busreq_rff (.din(lsu_busreq_m & ~flush_r & ~ld_full_hit_m), .dout(lsu_busreq_r), .clk(lsu_c2_r_clk), .*);
rvdff #(.WIDTH(1)) lsu_nonblock_load_valid_rff (.din(lsu_nonblock_load_valid_m), .dout(lsu_nonblock_load_valid_r), .clk(lsu_c2_r_clk), .*);
rvdff #(
.WIDTH(1)
) lsu_busreq_rff (
.din (lsu_busreq_m & ~flush_r & ~ld_full_hit_m),
.dout(lsu_busreq_r),
.clk (lsu_c2_r_clk),
.*
);
rvdff #(
.WIDTH(1)
) lsu_nonblock_load_valid_rff (
.din (lsu_nonblock_load_valid_m),
.dout(lsu_nonblock_load_valid_r),
.clk (lsu_c2_r_clk),
.*
);
endmodule // el2_lsu_bus_buffer

View File

@ -67,7 +67,9 @@ import el2_pkg::*;
input logic is_sideeffects_m, // lsu attribute is side_effects
input logic flush_m_up, // flush
input logic flush_r, // flush
input logic ldst_dual_d, ldst_dual_m, ldst_dual_r,
input logic ldst_dual_d,
ldst_dual_m,
ldst_dual_r,
output logic lsu_busreq_r, // bus request is in r
output logic lsu_bus_buffer_pend_any, // bus buffer has a pending bus entry
@ -186,9 +188,7 @@ import el2_pkg::*;
({4{lsu_pkt_m.word}} & 4'b1111);
// Read/Write Buffer
el2_lsu_bus_buffer #(.pt(pt)) bus_buffer (
.*
);
el2_lsu_bus_buffer #(.pt(pt)) bus_buffer (.*);
// Logic to determine if dc5 store can be coalesced or not with younger stores. Bypass ibuf if cannot colaesced
assign addr_match_dw_lo_r_m = (lsu_addr_r[31:3] == lsu_addr_m[31:3]);
@ -261,10 +261,29 @@ import el2_pkg::*;
// Fifo flops
rvdff #(.WIDTH(1)) clken_ff (.din(lsu_bus_clk_en), .dout(lsu_bus_clk_en_q), .clk(active_clk), .*);
rvdff #(
.WIDTH(1)
) clken_ff (
.din (lsu_bus_clk_en),
.dout(lsu_bus_clk_en_q),
.clk (active_clk),
.*
);
rvdff #(.WIDTH(1)) is_sideeffects_rff (.din(is_sideeffects_m), .dout(is_sideeffects_r), .clk(lsu_c1_r_clk), .*);
rvdff #(
.WIDTH(1)
) is_sideeffects_rff (
.din (is_sideeffects_m),
.dout(is_sideeffects_r),
.clk (lsu_c1_r_clk),
.*
);
rvdff #(4) lsu_byten_rff (.*, .din(ldst_byteen_m[3:0]), .dout(ldst_byteen_r[3:0]), .clk(lsu_c1_r_clk));
rvdff #(4) lsu_byten_rff (
.*,
.din (ldst_byteen_m[3:0]),
.dout(ldst_byteen_r[3:0]),
.clk (lsu_c1_r_clk)
);
endmodule // el2_lsu_bus_intf

View File

@ -110,31 +110,94 @@ import el2_pkg::*;
assign lsu_free_c2_clken = lsu_free_c1_clken | lsu_free_c1_clken_q | clk_override;
// Flops
rvdff #(1) lsu_free_c1_clkenff (.din(lsu_free_c1_clken), .dout(lsu_free_c1_clken_q), .clk(active_clk), .*);
rvdff #(1) lsu_free_c1_clkenff (
.din (lsu_free_c1_clken),
.dout(lsu_free_c1_clken_q),
.clk (active_clk),
.*
);
rvdff #(1) lsu_c1_m_clkenff (.din(lsu_c1_m_clken), .dout(lsu_c1_m_clken_q), .clk(lsu_free_c2_clk), .*);
rvdff #(1) lsu_c1_r_clkenff (.din(lsu_c1_r_clken), .dout(lsu_c1_r_clken_q), .clk(lsu_free_c2_clk), .*);
rvdff #(1) lsu_c1_m_clkenff (
.din (lsu_c1_m_clken),
.dout(lsu_c1_m_clken_q),
.clk (lsu_free_c2_clk),
.*
);
rvdff #(1) lsu_c1_r_clkenff (
.din (lsu_c1_r_clken),
.dout(lsu_c1_r_clken_q),
.clk (lsu_free_c2_clk),
.*
);
// Clock Headers
rvoclkhdr lsu_c1m_cgc ( .en(lsu_c1_m_clken), .l1clk(lsu_c1_m_clk), .* );
rvoclkhdr lsu_c1r_cgc ( .en(lsu_c1_r_clken), .l1clk(lsu_c1_r_clk), .* );
rvoclkhdr lsu_c1m_cgc (
.en(lsu_c1_m_clken),
.l1clk(lsu_c1_m_clk),
.*
);
rvoclkhdr lsu_c1r_cgc (
.en(lsu_c1_r_clken),
.l1clk(lsu_c1_r_clk),
.*
);
rvoclkhdr lsu_c2m_cgc ( .en(lsu_c2_m_clken), .l1clk(lsu_c2_m_clk), .* );
rvoclkhdr lsu_c2r_cgc ( .en(lsu_c2_r_clken), .l1clk(lsu_c2_r_clk), .* );
rvoclkhdr lsu_c2m_cgc (
.en(lsu_c2_m_clken),
.l1clk(lsu_c2_m_clk),
.*
);
rvoclkhdr lsu_c2r_cgc (
.en(lsu_c2_r_clken),
.l1clk(lsu_c2_r_clk),
.*
);
rvoclkhdr lsu_store_c1m_cgc (.en(lsu_store_c1_m_clken), .l1clk(lsu_store_c1_m_clk), .*);
rvoclkhdr lsu_store_c1r_cgc (.en(lsu_store_c1_r_clken), .l1clk(lsu_store_c1_r_clk), .*);
rvoclkhdr lsu_store_c1m_cgc (
.en(lsu_store_c1_m_clken),
.l1clk(lsu_store_c1_m_clk),
.*
);
rvoclkhdr lsu_store_c1r_cgc (
.en(lsu_store_c1_r_clken),
.l1clk(lsu_store_c1_r_clk),
.*
);
rvoclkhdr lsu_stbuf_c1_cgc ( .en(lsu_stbuf_c1_clken), .l1clk(lsu_stbuf_c1_clk), .* );
rvoclkhdr lsu_bus_ibuf_c1_cgc ( .en(lsu_bus_ibuf_c1_clken), .l1clk(lsu_bus_ibuf_c1_clk), .* );
rvoclkhdr lsu_bus_buf_c1_cgc ( .en(lsu_bus_buf_c1_clken), .l1clk(lsu_bus_buf_c1_clk), .* );
rvoclkhdr lsu_stbuf_c1_cgc (
.en(lsu_stbuf_c1_clken),
.l1clk(lsu_stbuf_c1_clk),
.*
);
rvoclkhdr lsu_bus_ibuf_c1_cgc (
.en(lsu_bus_ibuf_c1_clken),
.l1clk(lsu_bus_ibuf_c1_clk),
.*
);
rvoclkhdr lsu_bus_buf_c1_cgc (
.en(lsu_bus_buf_c1_clken),
.l1clk(lsu_bus_buf_c1_clk),
.*
);
assign lsu_busm_clken = (~lsu_bus_buffer_empty_any | lsu_busreq_r | clk_override) & lsu_bus_clk_en;
rvclkhdr lsu_bus_obuf_c1_cgc ( .en(lsu_bus_obuf_c1_clken), .l1clk(lsu_bus_obuf_c1_clk), .* );
rvclkhdr lsu_busm_cgc (.en(lsu_busm_clken), .l1clk(lsu_busm_clk), .*);
rvclkhdr lsu_bus_obuf_c1_cgc (
.en(lsu_bus_obuf_c1_clken),
.l1clk(lsu_bus_obuf_c1_clk),
.*
);
rvclkhdr lsu_busm_cgc (
.en(lsu_busm_clken),
.l1clk(lsu_busm_clk),
.*
);
rvoclkhdr lsu_free_cgc (.en(lsu_free_c2_clken), .l1clk(lsu_free_c2_clk), .*);
rvoclkhdr lsu_free_cgc (
.en(lsu_free_c2_clken),
.l1clk(lsu_free_c2_clk),
.*
);
endmodule

View File

@ -30,8 +30,7 @@ module el2_lsu_dccm_ctl
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic lsu_c2_m_clk, // clocks
input logic lsu_c2_r_clk, // clocks
input logic lsu_c1_r_clk, // clocks
@ -48,11 +47,14 @@ import el2_pkg::*;
input logic addr_in_dccm_d, // address maps to dccm
input logic addr_in_pic_d, // address maps to pic
input logic addr_in_pic_m, // address maps to pic
input logic addr_in_dccm_m, addr_in_dccm_r, // address in dccm per pipe stage
input logic addr_in_dccm_m,
addr_in_dccm_r, // address in dccm per pipe stage
input logic addr_in_pic_r, // address in pic per pipe stage
input logic lsu_raw_fwd_lo_r, lsu_raw_fwd_hi_r,
input logic lsu_raw_fwd_lo_r,
lsu_raw_fwd_hi_r,
input logic lsu_commit_r, // lsu instruction in r commits
input logic ldst_dual_m, ldst_dual_r,// load/store is unaligned at 32 bit boundary per pipe stage
input logic ldst_dual_m,
ldst_dual_r, // load/store is unaligned at 32 bit boundary per pipe stage
// lsu address down the pipe
input logic [ 31:0] lsu_addr_d,
@ -210,14 +212,52 @@ import el2_pkg::*;
assign lsu_rdata_r[(8*i)+7:8*i] = stbuf_fwdbyteen_r[i] ? stbuf_fwddata_r[(8*i)+7:8*i] :
(addr_in_pic_r ? picm_rd_data_r[(8*i)+7:8*i] : ({8{addr_in_dccm_r}} & dccm_rdata_r[(8*i)+7:8*i]));
end
rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_hi_r_ff (.*, .din(dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(dccm_rdata_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .en((lsu_dccm_rden_m & ldst_dual_m) | clk_override));
rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_lo_r_ff (.*, .din(dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(dccm_rdata_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .en(lsu_dccm_rden_m | clk_override));
rvdffe #(2*pt.DCCM_ECC_WIDTH) dccm_data_ecc_r_ff (.*, .din({dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0]}),
.dout({dccm_data_ecc_hi_r[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_r[pt.DCCM_ECC_WIDTH-1:0]}), .en(lsu_dccm_rden_m | clk_override));
rvdff #(8) stbuf_fwdbyteen_ff (.*, .din({stbuf_fwdbyteen_hi_m[3:0], stbuf_fwdbyteen_lo_m[3:0]}), .dout({stbuf_fwdbyteen_hi_r[3:0], stbuf_fwdbyteen_lo_r[3:0]}), .clk(lsu_c2_r_clk));
rvdffe #(64) stbuf_fwddata_ff (.*, .din({stbuf_fwddata_hi_m[31:0], stbuf_fwddata_lo_m[31:0]}), .dout({stbuf_fwddata_hi_r[31:0], stbuf_fwddata_lo_r[31:0]}), .en(stbuf_fwddata_en));
rvdffe #(32) picm_rddata_rff (.*, .din(picm_rd_data_m[31:0]), .dout(picm_rd_data_r[31:0]), .en(addr_in_pic_m | clk_override));
rvdff #(3) dma_mem_tag_rff (.*, .din(dma_mem_tag_m[2:0]), .dout(dma_mem_tag_r[2:0]), .clk(lsu_c1_r_clk));
rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_hi_r_ff (
.*,
.din (dccm_rdata_hi_m[pt.DCCM_DATA_WIDTH-1:0]),
.dout(dccm_rdata_hi_r[pt.DCCM_DATA_WIDTH-1:0]),
.en ((lsu_dccm_rden_m & ldst_dual_m) | clk_override)
);
rvdffe #(pt.DCCM_DATA_WIDTH) dccm_rdata_lo_r_ff (
.*,
.din (dccm_rdata_lo_m[pt.DCCM_DATA_WIDTH-1:0]),
.dout(dccm_rdata_lo_r[pt.DCCM_DATA_WIDTH-1:0]),
.en (lsu_dccm_rden_m | clk_override)
);
rvdffe #(2 * pt.DCCM_ECC_WIDTH) dccm_data_ecc_r_ff (
.*,
.din({
dccm_data_ecc_hi_m[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_m[pt.DCCM_ECC_WIDTH-1:0]
}),
.dout({
dccm_data_ecc_hi_r[pt.DCCM_ECC_WIDTH-1:0], dccm_data_ecc_lo_r[pt.DCCM_ECC_WIDTH-1:0]
}),
.en(lsu_dccm_rden_m | clk_override)
);
rvdff #(8) stbuf_fwdbyteen_ff (
.*,
.din ({stbuf_fwdbyteen_hi_m[3:0], stbuf_fwdbyteen_lo_m[3:0]}),
.dout({stbuf_fwdbyteen_hi_r[3:0], stbuf_fwdbyteen_lo_r[3:0]}),
.clk (lsu_c2_r_clk)
);
rvdffe #(64) stbuf_fwddata_ff (
.*,
.din ({stbuf_fwddata_hi_m[31:0], stbuf_fwddata_lo_m[31:0]}),
.dout({stbuf_fwddata_hi_r[31:0], stbuf_fwddata_lo_r[31:0]}),
.en (stbuf_fwddata_en)
);
rvdffe #(32) picm_rddata_rff (
.*,
.din (picm_rd_data_m[31:0]),
.dout(picm_rd_data_r[31:0]),
.en (addr_in_pic_m | clk_override)
);
rvdff #(3) dma_mem_tag_rff (
.*,
.din (dma_mem_tag_m[2:0]),
.dout(dma_mem_tag_r[2:0]),
.clk (lsu_c1_r_clk)
);
end else begin : L2U_Plus1_0
@ -248,7 +288,12 @@ import el2_pkg::*;
(addr_in_pic_m ? picm_rd_data_m[(8*i)+7:8*i] : ({8{addr_in_dccm_m}} & dccm_rdata_m[(8*i)+7:8*i]));
end
rvdffe #(32) lsu_ld_data_corr_rff(.*, .din(lsu_ld_data_corr_m[31:0]), .dout(lsu_ld_data_corr_r[31:0]), .en((lsu_pkt_m.valid & lsu_pkt_m.load & (addr_in_pic_m | addr_in_dccm_m)) | clk_override));
rvdffe #(32) lsu_ld_data_corr_rff (
.*,
.din (lsu_ld_data_corr_m[31:0]),
.dout(lsu_ld_data_corr_r[31:0]),
.en ((lsu_pkt_m.valid & lsu_pkt_m.load & (addr_in_pic_m | addr_in_dccm_m)) | clk_override)
);
end
assign kill_ecc_corr_lo_r = (((lsu_addr_d[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2]) | (end_addr_d[pt.DCCM_BITS-1:2] == lsu_addr_r[pt.DCCM_BITS-1:2])) & lsu_pkt_d.valid & lsu_pkt_d.store & lsu_pkt_d.dma & addr_in_dccm_d) |
@ -335,11 +380,37 @@ import el2_pkg::*;
((dccm_wren_Q & dccm_wr_bypass_d_m_hi_Q) ? dccm_wr_data_Q[(8*i)+7:(8*i)] : sec_data_hi_r[(8*i)+7:(8*i)]));
end
rvdff #(1) dccm_wren_ff (.*, .din(lsu_stbuf_commit_any), .dout(dccm_wren_Q), .clk(lsu_free_c2_clk)); // ECC load errors writing to dccm shouldn't fwd to stores in pipe
rvdffe #(32) dccm_wrdata_ff (.*, .din(stbuf_data_any[31:0]), .dout(dccm_wr_data_Q[31:0]), .en(lsu_stbuf_commit_any | clk_override), .clk(clk));
rvdff #(1) dccm_wrbyp_dm_loff (.*, .din(dccm_wr_bypass_d_m_lo), .dout(dccm_wr_bypass_d_m_lo_Q), .clk(lsu_free_c2_clk));
rvdff #(1) dccm_wrbyp_dm_hiff (.*, .din(dccm_wr_bypass_d_m_hi), .dout(dccm_wr_bypass_d_m_hi_Q), .clk(lsu_free_c2_clk));
rvdff #(32) store_data_rff (.*, .din(store_data_m[31:0]), .dout(store_data_r[31:0]), .clk(lsu_store_c1_r_clk));
rvdff #(1) dccm_wren_ff (
.*,
.din (lsu_stbuf_commit_any),
.dout(dccm_wren_Q),
.clk (lsu_free_c2_clk)
); // ECC load errors writing to dccm shouldn't fwd to stores in pipe
rvdffe #(32) dccm_wrdata_ff (
.*,
.din (stbuf_data_any[31:0]),
.dout(dccm_wr_data_Q[31:0]),
.en (lsu_stbuf_commit_any | clk_override),
.clk (clk)
);
rvdff #(1) dccm_wrbyp_dm_loff (
.*,
.din (dccm_wr_bypass_d_m_lo),
.dout(dccm_wr_bypass_d_m_lo_Q),
.clk (lsu_free_c2_clk)
);
rvdff #(1) dccm_wrbyp_dm_hiff (
.*,
.din (dccm_wr_bypass_d_m_hi),
.dout(dccm_wr_bypass_d_m_hi_Q),
.clk (lsu_free_c2_clk)
);
rvdff #(32) store_data_rff (
.*,
.din (store_data_m[31:0]),
.dout(store_data_r[31:0]),
.clk (lsu_store_c1_r_clk)
);
end else begin : L2U1_Plus1_0
@ -362,8 +433,19 @@ import el2_pkg::*;
end
assign store_data_r[31:0] = 32'({store_data_hi_r[31:0],store_data_lo_r[31:0]} >> 8*lsu_addr_r[1:0]) & store_data_mask[31:0];
rvdffe #(pt.DCCM_DATA_WIDTH) store_data_hi_rff (.*, .din(store_data_hi_r_in[pt.DCCM_DATA_WIDTH-1:0]), .dout(store_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .en((ldst_dual_m & lsu_pkt_m.valid & lsu_pkt_m.store) | clk_override), .clk(clk));
rvdff #(pt.DCCM_DATA_WIDTH) store_data_lo_rff (.*, .din(store_data_lo_r_in[pt.DCCM_DATA_WIDTH-1:0]), .dout(store_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .clk(lsu_store_c1_r_clk));
rvdffe #(pt.DCCM_DATA_WIDTH) store_data_hi_rff (
.*,
.din (store_data_hi_r_in[pt.DCCM_DATA_WIDTH-1:0]),
.dout(store_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]),
.en ((ldst_dual_m & lsu_pkt_m.valid & lsu_pkt_m.store) | clk_override),
.clk (clk)
);
rvdff #(pt.DCCM_DATA_WIDTH) store_data_lo_rff (
.*,
.din (store_data_lo_r_in[pt.DCCM_DATA_WIDTH-1:0]),
.dout(store_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]),
.clk (lsu_store_c1_r_clk)
);
end
@ -387,17 +469,54 @@ import el2_pkg::*;
assign picm_rd_data_m[63:0] = {picm_rd_data[31:0], picm_rd_data[31:0]};
if (pt.DCCM_ENABLE == 1) begin : Gen_dccm_enable
rvdff #(1) dccm_rden_mff (.*, .din(lsu_dccm_rden_d), .dout(lsu_dccm_rden_m), .clk(lsu_c2_m_clk));
rvdff #(1) dccm_rden_rff (.*, .din(lsu_dccm_rden_m), .dout(lsu_dccm_rden_r), .clk(lsu_c2_r_clk));
rvdff #(1) dccm_rden_mff (
.*,
.din (lsu_dccm_rden_d),
.dout(lsu_dccm_rden_m),
.clk (lsu_c2_m_clk)
);
rvdff #(1) dccm_rden_rff (
.*,
.din (lsu_dccm_rden_m),
.dout(lsu_dccm_rden_r),
.clk (lsu_c2_r_clk)
);
// ECC correction flops since dccm write happens next cycle
// We are writing to dccm in r+1 for ecc correction since fast_int needs to be blocked in decode - 1. We can probably write in r for plus0 configuration since we know ecc error in M.
// In that case these (_ff) flops are needed only in plus1 configuration
rvdff #(1) ld_double_ecc_error_rff (.*, .din(lsu_double_ecc_error_r), .dout(lsu_double_ecc_error_r_ff), .clk(lsu_free_c2_clk));
rvdff #(1) ld_single_ecc_error_hi_rff (.*, .din(ld_single_ecc_error_hi_r_ns), .dout(ld_single_ecc_error_hi_r_ff), .clk(lsu_free_c2_clk));
rvdff #(1) ld_single_ecc_error_lo_rff (.*, .din(ld_single_ecc_error_lo_r_ns), .dout(ld_single_ecc_error_lo_r_ff), .clk(lsu_free_c2_clk));
rvdffe #(pt.DCCM_BITS) ld_sec_addr_hi_rff (.*, .din(end_addr_r[pt.DCCM_BITS-1:0]), .dout(ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk));
rvdffe #(pt.DCCM_BITS) ld_sec_addr_lo_rff (.*, .din(lsu_addr_r[pt.DCCM_BITS-1:0]), .dout(ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk));
rvdff #(1) ld_double_ecc_error_rff (
.*,
.din (lsu_double_ecc_error_r),
.dout(lsu_double_ecc_error_r_ff),
.clk (lsu_free_c2_clk)
);
rvdff #(1) ld_single_ecc_error_hi_rff (
.*,
.din (ld_single_ecc_error_hi_r_ns),
.dout(ld_single_ecc_error_hi_r_ff),
.clk (lsu_free_c2_clk)
);
rvdff #(1) ld_single_ecc_error_lo_rff (
.*,
.din (ld_single_ecc_error_lo_r_ns),
.dout(ld_single_ecc_error_lo_r_ff),
.clk (lsu_free_c2_clk)
);
rvdffe #(pt.DCCM_BITS) ld_sec_addr_hi_rff (
.*,
.din (end_addr_r[pt.DCCM_BITS-1:0]),
.dout(ld_sec_addr_hi_r_ff[pt.DCCM_BITS-1:0]),
.en (ld_single_ecc_error_r | clk_override),
.clk (clk)
);
rvdffe #(pt.DCCM_BITS) ld_sec_addr_lo_rff (
.*,
.din (lsu_addr_r[pt.DCCM_BITS-1:0]),
.dout(ld_sec_addr_lo_r_ff[pt.DCCM_BITS-1:0]),
.en (ld_single_ecc_error_r | clk_override),
.clk (clk)
);
end else begin : Gen_dccm_disable
assign lsu_dccm_rden_m = '0;

View File

@ -34,10 +34,7 @@
.DS(dccm_ext_in_pkt[i].DS),\
.SD(dccm_ext_in_pkt[i].SD),\
.TEST_RNM(dccm_ext_in_pkt[i].TEST_RNM),\
.BC1(dccm_ext_in_pkt[i].BC1), \
.BC2(dccm_ext_in_pkt[i].BC2), \
.BC1(dccm_ext_in_pkt[i].BC1),.BC2(dccm_ext_in_pkt[i].BC2),
module el2_lsu_dccm_mem
import el2_pkg::*;

View File

@ -29,8 +29,7 @@ module el2_lsu_ecc
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
input logic lsu_c2_r_clk, // clock
input logic clk_override, // Override non-functional clock gating
@ -159,12 +158,50 @@ import el2_pkg::*;
assign lsu_double_ecc_error_m = double_ecc_error_hi_m | double_ecc_error_lo_m;
// Flops
rvdff #(1) lsu_single_ecc_err_r (.din(lsu_single_ecc_error_m), .dout(lsu_single_ecc_error_r), .clk(lsu_c2_r_clk), .*);
rvdff #(1) lsu_double_ecc_err_r (.din(lsu_double_ecc_error_m), .dout(lsu_double_ecc_error_r), .clk(lsu_c2_r_clk), .*);
rvdff #(.WIDTH(1)) ldst_sec_lo_rff (.din(single_ecc_error_lo_any), .dout(single_ecc_error_lo_r), .clk(lsu_c2_r_clk), .*);
rvdff #(.WIDTH(1)) ldst_sec_hi_rff (.din(single_ecc_error_hi_any), .dout(single_ecc_error_hi_r), .clk(lsu_c2_r_clk), .*);
rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_hi_rff (.din(sec_data_hi_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .en(lsu_single_ecc_error_m | clk_override), .*);
rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_lo_rff (.din(sec_data_lo_m[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .en(lsu_single_ecc_error_m | clk_override), .*);
rvdff #(1) lsu_single_ecc_err_r (
.din (lsu_single_ecc_error_m),
.dout(lsu_single_ecc_error_r),
.clk (lsu_c2_r_clk),
.*
);
rvdff #(1) lsu_double_ecc_err_r (
.din (lsu_double_ecc_error_m),
.dout(lsu_double_ecc_error_r),
.clk (lsu_c2_r_clk),
.*
);
rvdff #(
.WIDTH(1)
) ldst_sec_lo_rff (
.din (single_ecc_error_lo_any),
.dout(single_ecc_error_lo_r),
.clk (lsu_c2_r_clk),
.*
);
rvdff #(
.WIDTH(1)
) ldst_sec_hi_rff (
.din (single_ecc_error_hi_any),
.dout(single_ecc_error_hi_r),
.clk (lsu_c2_r_clk),
.*
);
rvdffe #(
.WIDTH(pt.DCCM_DATA_WIDTH)
) sec_data_hi_rff (
.din (sec_data_hi_m[pt.DCCM_DATA_WIDTH-1:0]),
.dout(sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]),
.en (lsu_single_ecc_error_m | clk_override),
.*
);
rvdffe #(
.WIDTH(pt.DCCM_DATA_WIDTH)
) sec_data_lo_rff (
.din (sec_data_lo_m[pt.DCCM_DATA_WIDTH-1:0]),
.dout(sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]),
.en (lsu_single_ecc_error_m | clk_override),
.*
);
end
@ -234,8 +271,24 @@ import el2_pkg::*;
assign double_ecc_error_lo_any = '0;
end
rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_hi_rplus1ff (.din(sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk), .*);
rvdffe #(.WIDTH(pt.DCCM_DATA_WIDTH)) sec_data_lo_rplus1ff (.din(sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]), .dout(sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]), .en(ld_single_ecc_error_r | clk_override), .clk(clk), .*);
rvdffe #(
.WIDTH(pt.DCCM_DATA_WIDTH)
) sec_data_hi_rplus1ff (
.din (sec_data_hi_r[pt.DCCM_DATA_WIDTH-1:0]),
.dout(sec_data_hi_r_ff[pt.DCCM_DATA_WIDTH-1:0]),
.en (ld_single_ecc_error_r | clk_override),
.clk (clk),
.*
);
rvdffe #(
.WIDTH(pt.DCCM_DATA_WIDTH)
) sec_data_lo_rplus1ff (
.din (sec_data_lo_r[pt.DCCM_DATA_WIDTH-1:0]),
.dout(sec_data_lo_r_ff[pt.DCCM_DATA_WIDTH-1:0]),
.en (ld_single_ecc_error_r | clk_override),
.clk (clk),
.*
);
endmodule // el2_lsu_ecc

View File

@ -153,7 +153,8 @@ import el2_pkg::*;
assign rs1_d[31:0] = (lsu_pkt_d.load_ldst_bypass_d) ? lsu_result_m[31:0] : rs1_d_raw[31:0];
// generate the ls address
rvlsadder lsadder (.rs1(rs1_d[31:0]),
rvlsadder lsadder (
.rs1(rs1_d[31:0]),
.offset(offset_d[11:0]),
.dout(full_addr_d[31:0])
);
@ -191,11 +192,36 @@ import el2_pkg::*;
assign lsu_fir_error[1:0] = fir_nondccm_access_error_r ? 2'b11 : (fir_dccm_access_error_r ? 2'b10 : ((lsu_pkt_r.fast_int & lsu_double_ecc_error_r) ? 2'b01 : 2'b00));
rvdff #(1) access_fault_rff (.din(access_fault_m), .dout(access_fault_r), .clk(lsu_c1_r_clk), .*);
rvdff #(1) misaligned_fault_rff (.din(misaligned_fault_m), .dout(misaligned_fault_r), .clk(lsu_c1_r_clk), .*);
rvdff #(4) exc_mscause_rff (.din(exc_mscause_m[3:0]), .dout(exc_mscause_r[3:0]), .clk(lsu_c1_r_clk), .*);
rvdff #(1) fir_dccm_access_error_mff (.din(fir_dccm_access_error_m), .dout(fir_dccm_access_error_r), .clk(lsu_c1_r_clk), .*);
rvdff #(1) fir_nondccm_access_error_mff (.din(fir_nondccm_access_error_m), .dout(fir_nondccm_access_error_r), .clk(lsu_c1_r_clk), .*);
rvdff #(1) access_fault_rff (
.din (access_fault_m),
.dout(access_fault_r),
.clk (lsu_c1_r_clk),
.*
);
rvdff #(1) misaligned_fault_rff (
.din (misaligned_fault_m),
.dout(misaligned_fault_r),
.clk (lsu_c1_r_clk),
.*
);
rvdff #(4) exc_mscause_rff (
.din (exc_mscause_m[3:0]),
.dout(exc_mscause_r[3:0]),
.clk (lsu_c1_r_clk),
.*
);
rvdff #(1) fir_dccm_access_error_mff (
.din (fir_dccm_access_error_m),
.dout(fir_dccm_access_error_r),
.clk (lsu_c1_r_clk),
.*
);
rvdff #(1) fir_nondccm_access_error_mff (
.din (fir_nondccm_access_error_m),
.dout(fir_nondccm_access_error_r),
.clk (lsu_c1_r_clk),
.*
);
end else begin : L2U_Plus1_0
logic [1:0] lsu_fir_error_m;
@ -210,10 +236,32 @@ import el2_pkg::*;
assign lsu_fir_error_m[1:0] = fir_nondccm_access_error_m ? 2'b11 : (fir_dccm_access_error_m ? 2'b10 : ((lsu_pkt_m.fast_int & lsu_double_ecc_error_m) ? 2'b01 : 2'b00));
rvdff #(1) lsu_exc_valid_rff (.*, .din(lsu_error_pkt_m.exc_valid), .dout(lsu_error_pkt_r.exc_valid), .clk(lsu_c2_r_clk));
rvdff #(1) lsu_single_ecc_error_rff(.*, .din(lsu_error_pkt_m.single_ecc_error), .dout(lsu_error_pkt_r.single_ecc_error), .clk(lsu_c2_r_clk));
rvdffe #($bits(el2_lsu_error_pkt_t)-2) lsu_error_pkt_rff (.*, .din(lsu_error_pkt_m[$bits(el2_lsu_error_pkt_t)-1:2]), .dout(lsu_error_pkt_r[$bits(el2_lsu_error_pkt_t)-1:2]), .en(lsu_error_pkt_m.exc_valid | lsu_error_pkt_m.single_ecc_error | clk_override));
rvdff #(2) lsu_fir_error_rff (.*, .din(lsu_fir_error_m[1:0]), .dout(lsu_fir_error[1:0]), .clk(lsu_c2_r_clk));
rvdff #(1) lsu_exc_valid_rff (
.*,
.din (lsu_error_pkt_m.exc_valid),
.dout(lsu_error_pkt_r.exc_valid),
.clk (lsu_c2_r_clk)
);
rvdff #(1) lsu_single_ecc_error_rff (
.*,
.din (lsu_error_pkt_m.single_ecc_error),
.dout(lsu_error_pkt_r.single_ecc_error),
.clk (lsu_c2_r_clk)
);
rvdffe #($bits(
el2_lsu_error_pkt_t
) - 2) lsu_error_pkt_rff (
.*,
.din (lsu_error_pkt_m[$bits(el2_lsu_error_pkt_t)-1:2]),
.dout(lsu_error_pkt_r[$bits(el2_lsu_error_pkt_t)-1:2]),
.en (lsu_error_pkt_m.exc_valid | lsu_error_pkt_m.single_ecc_error | clk_override)
);
rvdff #(2) lsu_fir_error_rff (
.*,
.din (lsu_fir_error_m[1:0]),
.dout(lsu_fir_error[1:0]),
.clk (lsu_c2_r_clk)
);
end
//Create DMA packet
@ -240,11 +288,35 @@ import el2_pkg::*;
end
// C2 clock for valid and C1 for other bits of packet
rvdff #(1) lsu_pkt_vldmff (.*, .din(lsu_pkt_m_in.valid), .dout(lsu_pkt_m.valid), .clk(lsu_c2_m_clk));
rvdff #(1) lsu_pkt_vldrff (.*, .din(lsu_pkt_r_in.valid), .dout(lsu_pkt_r.valid), .clk(lsu_c2_r_clk));
rvdff #(1) lsu_pkt_vldmff (
.*,
.din (lsu_pkt_m_in.valid),
.dout(lsu_pkt_m.valid),
.clk (lsu_c2_m_clk)
);
rvdff #(1) lsu_pkt_vldrff (
.*,
.din (lsu_pkt_r_in.valid),
.dout(lsu_pkt_r.valid),
.clk (lsu_c2_r_clk)
);
rvdff #($bits(el2_lsu_pkt_t)-1) lsu_pkt_mff (.*, .din(lsu_pkt_m_in[$bits(el2_lsu_pkt_t)-1:1]), .dout(lsu_pkt_m[$bits(el2_lsu_pkt_t)-1:1]), .clk(lsu_c1_m_clk));
rvdff #($bits(el2_lsu_pkt_t)-1) lsu_pkt_rff (.*, .din(lsu_pkt_r_in[$bits(el2_lsu_pkt_t)-1:1]), .dout(lsu_pkt_r[$bits(el2_lsu_pkt_t)-1:1]), .clk(lsu_c1_r_clk));
rvdff #($bits(
el2_lsu_pkt_t
) - 1) lsu_pkt_mff (
.*,
.din (lsu_pkt_m_in[$bits(el2_lsu_pkt_t)-1:1]),
.dout(lsu_pkt_m[$bits(el2_lsu_pkt_t)-1:1]),
.clk (lsu_c1_m_clk)
);
rvdff #($bits(
el2_lsu_pkt_t
) - 1) lsu_pkt_rff (
.*,
.din (lsu_pkt_r_in[$bits(el2_lsu_pkt_t)-1:1]),
.dout(lsu_pkt_r[$bits(el2_lsu_pkt_t)-1:1]),
.clk (lsu_c1_r_clk)
);
@ -306,36 +378,131 @@ import el2_pkg::*;
assign store_data_m[31:0] = (picm_mask_data_m[31:0] | {32{~addr_in_pic_m}}) & ((lsu_pkt_m.store_data_bypass_m) ? lsu_result_m[31:0] : store_data_pre_m[31:0]);
rvdff #(32) sdmff (.*, .din(store_data_m_in[31:0]), .dout(store_data_pre_m[31:0]), .clk(lsu_store_c1_m_clk));
rvdff #(32) sdmff (
.*,
.din (store_data_m_in[31:0]),
.dout(store_data_pre_m[31:0]),
.clk (lsu_store_c1_m_clk)
);
rvdff #(32) samff (.*, .din(lsu_addr_d[31:0]), .dout(lsu_addr_m[31:0]), .clk(lsu_c1_m_clk));
rvdff #(32) sarff (.*, .din(lsu_addr_m[31:0]), .dout(lsu_addr_r[31:0]), .clk(lsu_c1_r_clk));
rvdff #(32) samff (
.*,
.din (lsu_addr_d[31:0]),
.dout(lsu_addr_m[31:0]),
.clk (lsu_c1_m_clk)
);
rvdff #(32) sarff (
.*,
.din (lsu_addr_m[31:0]),
.dout(lsu_addr_r[31:0]),
.clk (lsu_c1_r_clk)
);
assign end_addr_m[31:3] = ldst_dual_m ? end_addr_pre_m[31:3] : lsu_addr_m[31:3]; // This is for power saving
assign end_addr_r[31:3] = ldst_dual_r ? end_addr_pre_r[31:3] : lsu_addr_r[31:3]; // This is for power saving
rvdffe #(29) end_addr_hi_mff (.*, .din(end_addr_d[31:3]), .dout(end_addr_pre_m[31:3]), .en((lsu_pkt_d.valid & ldst_dual_d) | clk_override));
rvdffe #(29) end_addr_hi_rff (.*, .din(end_addr_m[31:3]), .dout(end_addr_pre_r[31:3]), .en((lsu_pkt_m.valid & ldst_dual_m) | clk_override));
rvdffe #(29) end_addr_hi_mff (
.*,
.din (end_addr_d[31:3]),
.dout(end_addr_pre_m[31:3]),
.en ((lsu_pkt_d.valid & ldst_dual_d) | clk_override)
);
rvdffe #(29) end_addr_hi_rff (
.*,
.din (end_addr_m[31:3]),
.dout(end_addr_pre_r[31:3]),
.en ((lsu_pkt_m.valid & ldst_dual_m) | clk_override)
);
rvdff #(3) end_addr_lo_mff (.*, .din(end_addr_d[2:0]), .dout(end_addr_m[2:0]), .clk(lsu_c1_m_clk));
rvdff #(3) end_addr_lo_rff (.*, .din(end_addr_m[2:0]), .dout(end_addr_r[2:0]), .clk(lsu_c1_r_clk));
rvdff #(3) end_addr_lo_mff (
.*,
.din (end_addr_d[2:0]),
.dout(end_addr_m[2:0]),
.clk (lsu_c1_m_clk)
);
rvdff #(3) end_addr_lo_rff (
.*,
.din (end_addr_m[2:0]),
.dout(end_addr_r[2:0]),
.clk (lsu_c1_r_clk)
);
rvdff #(1) addr_in_dccm_mff(.din(addr_in_dccm_d), .dout(addr_in_dccm_m), .clk(lsu_c1_m_clk), .*);
rvdff #(1) addr_in_dccm_rff(.din(addr_in_dccm_m), .dout(addr_in_dccm_r), .clk(lsu_c1_r_clk), .*);
rvdff #(1) addr_in_dccm_mff (
.din (addr_in_dccm_d),
.dout(addr_in_dccm_m),
.clk (lsu_c1_m_clk),
.*
);
rvdff #(1) addr_in_dccm_rff (
.din (addr_in_dccm_m),
.dout(addr_in_dccm_r),
.clk (lsu_c1_r_clk),
.*
);
rvdff #(1) addr_in_pic_mff(.din(addr_in_pic_d), .dout(addr_in_pic_m), .clk(lsu_c1_m_clk), .*);
rvdff #(1) addr_in_pic_rff(.din(addr_in_pic_m), .dout(addr_in_pic_r), .clk(lsu_c1_r_clk), .*);
rvdff #(1) addr_in_pic_mff (
.din (addr_in_pic_d),
.dout(addr_in_pic_m),
.clk (lsu_c1_m_clk),
.*
);
rvdff #(1) addr_in_pic_rff (
.din (addr_in_pic_m),
.dout(addr_in_pic_r),
.clk (lsu_c1_r_clk),
.*
);
rvdff #(1) addr_external_mff(.din(addr_external_d), .dout(addr_external_m), .clk(lsu_c1_m_clk), .*);
rvdff #(1) addr_external_rff(.din(addr_external_m), .dout(addr_external_r), .clk(lsu_c1_r_clk), .*);
rvdff #(1) addr_external_mff (
.din (addr_external_d),
.dout(addr_external_m),
.clk (lsu_c1_m_clk),
.*
);
rvdff #(1) addr_external_rff (
.din (addr_external_m),
.dout(addr_external_r),
.clk (lsu_c1_r_clk),
.*
);
rvdff #(1) access_fault_mff (.din(access_fault_d), .dout(access_fault_m), .clk(lsu_c1_m_clk), .*);
rvdff #(1) misaligned_fault_mff (.din(misaligned_fault_d), .dout(misaligned_fault_m), .clk(lsu_c1_m_clk), .*);
rvdff #(4) exc_mscause_mff (.din(exc_mscause_d[3:0]), .dout(exc_mscause_m[3:0]), .clk(lsu_c1_m_clk), .*);
rvdff #(1) access_fault_mff (
.din (access_fault_d),
.dout(access_fault_m),
.clk (lsu_c1_m_clk),
.*
);
rvdff #(1) misaligned_fault_mff (
.din (misaligned_fault_d),
.dout(misaligned_fault_m),
.clk (lsu_c1_m_clk),
.*
);
rvdff #(4) exc_mscause_mff (
.din (exc_mscause_d[3:0]),
.dout(exc_mscause_m[3:0]),
.clk (lsu_c1_m_clk),
.*
);
rvdff #(1) fir_dccm_access_error_mff (.din(fir_dccm_access_error_d), .dout(fir_dccm_access_error_m), .clk(lsu_c1_m_clk), .*);
rvdff #(1) fir_nondccm_access_error_mff (.din(fir_nondccm_access_error_d), .dout(fir_nondccm_access_error_m), .clk(lsu_c1_m_clk), .*);
rvdff #(1) fir_dccm_access_error_mff (
.din (fir_dccm_access_error_d),
.dout(fir_dccm_access_error_m),
.clk (lsu_c1_m_clk),
.*
);
rvdff #(1) fir_nondccm_access_error_mff (
.din (fir_nondccm_access_error_d),
.dout(fir_nondccm_access_error_m),
.clk (lsu_c1_m_clk),
.*
);
rvdffe #(32) bus_read_data_r_ff (.*, .din(bus_read_data_m[31:0]), .dout(bus_read_data_r[31:0]), .en(addr_external_m | clk_override));
rvdffe #(32) bus_read_data_r_ff (
.*,
.din (bus_read_data_m[31:0]),
.dout(bus_read_data_r[31:0]),
.en (addr_external_m | clk_override)
);
endmodule

View File

@ -31,8 +31,7 @@ module el2_lsu_stbuf
import el2_pkg::*;
#(
`include "el2_param.vh"
)
(
) (
input logic clk, // core clock
input logic rst_l, // reset
@ -67,7 +66,9 @@ import el2_pkg::*;
input logic [31:0] end_addr_m, // lsu end address M-stage - needed to check unaligned
input logic [31:0] end_addr_r, // lsu end address R-stage - needed to check unaligned
input logic ldst_dual_d, ldst_dual_m, ldst_dual_r,
input logic ldst_dual_d,
ldst_dual_m,
ldst_dual_r,
input logic addr_in_dccm_m, // address is in dccm
input logic addr_in_dccm_r, // address is in dccm
@ -130,7 +131,8 @@ import el2_pkg::*;
logic [BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_pre_m, stbuf_fwdbyteen_lo_pre_m;
// logic to detect matching from the pipe - needed for store - load forwarding
logic [BYTE_WIDTH-1:0] ld_byte_rhit_lo_lo, ld_byte_rhit_hi_lo, ld_byte_rhit_lo_hi, ld_byte_rhit_hi_hi;
logic [BYTE_WIDTH-1:0]
ld_byte_rhit_lo_lo, ld_byte_rhit_hi_lo, ld_byte_rhit_lo_hi, ld_byte_rhit_hi_hi;
logic ld_addr_rhit_lo_lo, ld_addr_rhit_hi_lo, ld_addr_rhit_lo_hi, ld_addr_rhit_hi_hi;
logic [BYTE_WIDTH-1:0] ld_byte_hit_lo, ld_byte_rhit_lo;
@ -167,8 +169,16 @@ import el2_pkg::*;
// Store Buffer coalescing
for (genvar i = 0; i < DEPTH; i++) begin : FindMatchEntry
assign store_matchvec_lo_r[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == lsu_addr_r[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & ~stbuf_reset[i];
assign store_matchvec_hi_r[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == end_addr_r[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & dual_stbuf_write_r & ~stbuf_reset[i];
assign store_matchvec_lo_r[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(
BYTE_WIDTH
)] == lsu_addr_r[pt.LSU_SB_BITS-1:$clog2(
BYTE_WIDTH
)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & ~stbuf_reset[i];
assign store_matchvec_hi_r[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(
BYTE_WIDTH
)] == end_addr_r[pt.LSU_SB_BITS-1:$clog2(
BYTE_WIDTH
)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & dual_stbuf_write_r & ~stbuf_reset[i];
end : FindMatchEntry
assign store_coalesce_lo_r = |store_matchvec_lo_r[DEPTH-1:0];
@ -204,11 +214,52 @@ import el2_pkg::*;
assign stbuf_datain[i][31:24] = sel_lo[i] ? ((~stbuf_byteen[i][3] | store_byteen_lo_r[3]) ? store_datafn_lo_r[31:24] : stbuf_data[i][31:24]) :
((~stbuf_byteen[i][3] | store_byteen_hi_r[3]) ? store_datafn_hi_r[31:24] : stbuf_data[i][31:24]);
rvdffsc #(.WIDTH(1)) stbuf_vldff (.din(1'b1), .dout(stbuf_vld[i]), .en(stbuf_wr_en[i]), .clear(stbuf_reset[i]), .clk(lsu_free_c2_clk), .*);
rvdffsc #(.WIDTH(1)) stbuf_killff (.din(1'b1), .dout(stbuf_dma_kill[i]), .en(stbuf_dma_kill_en[i]), .clear(stbuf_reset[i]), .clk(lsu_free_c2_clk), .*);
rvdffe #(.WIDTH(pt.LSU_SB_BITS)) stbuf_addrff (.din(stbuf_addrin[i][pt.LSU_SB_BITS-1:0]), .dout(stbuf_addr[i][pt.LSU_SB_BITS-1:0]), .en(stbuf_wr_en[i]), .*);
rvdffsc #(.WIDTH(BYTE_WIDTH)) stbuf_byteenff (.din(stbuf_byteenin[i][BYTE_WIDTH-1:0]), .dout(stbuf_byteen[i][BYTE_WIDTH-1:0]), .en(stbuf_wr_en[i]), .clear(stbuf_reset[i]), .clk(lsu_stbuf_c1_clk), .*);
rvdffe #(.WIDTH(DATA_WIDTH)) stbuf_dataff (.din(stbuf_datain[i][DATA_WIDTH-1:0]), .dout(stbuf_data[i][DATA_WIDTH-1:0]), .en(stbuf_wr_en[i]), .*);
rvdffsc #(
.WIDTH(1)
) stbuf_vldff (
.din(1'b1),
.dout(stbuf_vld[i]),
.en(stbuf_wr_en[i]),
.clear(stbuf_reset[i]),
.clk(lsu_free_c2_clk),
.*
);
rvdffsc #(
.WIDTH(1)
) stbuf_killff (
.din(1'b1),
.dout(stbuf_dma_kill[i]),
.en(stbuf_dma_kill_en[i]),
.clear(stbuf_reset[i]),
.clk(lsu_free_c2_clk),
.*
);
rvdffe #(
.WIDTH(pt.LSU_SB_BITS)
) stbuf_addrff (
.din (stbuf_addrin[i][pt.LSU_SB_BITS-1:0]),
.dout(stbuf_addr[i][pt.LSU_SB_BITS-1:0]),
.en (stbuf_wr_en[i]),
.*
);
rvdffsc #(
.WIDTH(BYTE_WIDTH)
) stbuf_byteenff (
.din(stbuf_byteenin[i][BYTE_WIDTH-1:0]),
.dout(stbuf_byteen[i][BYTE_WIDTH-1:0]),
.en(stbuf_wr_en[i]),
.clear(stbuf_reset[i]),
.clk(lsu_stbuf_c1_clk),
.*
);
rvdffe #(
.WIDTH(DATA_WIDTH)
) stbuf_dataff (
.din (stbuf_datain[i][DATA_WIDTH-1:0]),
.dout(stbuf_data[i][DATA_WIDTH-1:0]),
.en (stbuf_wr_en[i]),
.*
);
end
end else begin : Gen_dccm_disable
assign stbuf_wr_en[DEPTH-1:0] = '0;
@ -253,17 +304,29 @@ import el2_pkg::*;
assign lsu_stbuf_empty_any = (stbuf_numvld_any[3:0] == 4'b0);
// Load forwarding logic from the store queue
assign cmpaddr_hi_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] = end_addr_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)];
assign cmpaddr_hi_m[pt.LSU_SB_BITS-1:$clog2(
BYTE_WIDTH
)] = end_addr_m[pt.LSU_SB_BITS-1:$clog2(
BYTE_WIDTH
)];
assign cmpaddr_lo_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] = lsu_addr_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)];
assign cmpaddr_lo_m[pt.LSU_SB_BITS-1:$clog2(
BYTE_WIDTH
)] = lsu_addr_m[pt.LSU_SB_BITS-1:$clog2(
BYTE_WIDTH
)];
always_comb begin : GenLdFwd
stbuf_fwdbyteen_hi_pre_m[BYTE_WIDTH-1:0] = '0;
stbuf_fwdbyteen_lo_pre_m[BYTE_WIDTH-1:0] = '0;
for (int i = 0; i < DEPTH; i++) begin
stbuf_match_hi[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & addr_in_dccm_m;
stbuf_match_lo[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_lo_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & stbuf_vld[i] & ~stbuf_dma_kill[i] & addr_in_dccm_m;
stbuf_match_hi[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] ==
cmpaddr_hi_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
stbuf_vld[i] & ~stbuf_dma_kill[i] & addr_in_dccm_m;
stbuf_match_lo[i] = (stbuf_addr[i][pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] ==
cmpaddr_lo_m[pt.LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) &
stbuf_vld[i] & ~stbuf_dma_kill[i] & addr_in_dccm_m;
// Kill the store buffer entry if there is a dma store since it already updated the dccm
stbuf_dma_kill_en[i] = (stbuf_match_hi[i] | stbuf_match_lo[i]) & lsu_pkt_m.valid & lsu_pkt_m.dma & lsu_pkt_m.store;
@ -333,8 +396,24 @@ import el2_pkg::*;
end
// Flops
rvdffs #(.WIDTH(DEPTH_LOG2)) WrPtrff (.din(NxtWrPtr[DEPTH_LOG2-1:0]), .dout(WrPtr[DEPTH_LOG2-1:0]), .en(WrPtrEn), .clk(lsu_stbuf_c1_clk), .*);
rvdffs #(.WIDTH(DEPTH_LOG2)) RdPtrff (.din(NxtRdPtr[DEPTH_LOG2-1:0]), .dout(RdPtr[DEPTH_LOG2-1:0]), .en(RdPtrEn), .clk(lsu_stbuf_c1_clk), .*);
rvdffs #(
.WIDTH(DEPTH_LOG2)
) WrPtrff (
.din (NxtWrPtr[DEPTH_LOG2-1:0]),
.dout(WrPtr[DEPTH_LOG2-1:0]),
.en (WrPtrEn),
.clk (lsu_stbuf_c1_clk),
.*
);
rvdffs #(
.WIDTH(DEPTH_LOG2)
) RdPtrff (
.din (NxtRdPtr[DEPTH_LOG2-1:0]),
.dout(RdPtr[DEPTH_LOG2-1:0]),
.en (RdPtrEn),
.clk (lsu_stbuf_c1_clk),
.*
);
endmodule

View File

@ -57,7 +57,12 @@ import el2_pkg::*;
assign lsu_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select}} & ldst_addr_trigger_m[31:0]) |
({32{trigger_pkt_any[i].select & trigger_pkt_any[i].store}} & store_data_trigger_m[31:0]);
rvmaskandmatch trigger_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(lsu_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(lsu_trigger_data_match[i]));
rvmaskandmatch trigger_match (
.mask (trigger_pkt_any[i].tdata2[31:0]),
.data (lsu_match_data[i][31:0]),
.masken(trigger_pkt_any[i].match),
.match (lsu_trigger_data_match[i])
);
assign lsu_trigger_match_m[i] = lsu_pkt_m.valid & ~lsu_pkt_m.dma & trigger_enable &
((trigger_pkt_any[i].store & lsu_pkt_m.store) | (trigger_pkt_any[i].load & lsu_pkt_m.load & ~trigger_pkt_any[i].select)) &