From 46f61f580fbcdea7159acbe31320a871928e3983 Mon Sep 17 00:00:00 2001 From: Stefan Wallentowitz Date: Sun, 27 Jan 2019 17:56:53 +0100 Subject: [PATCH] Whitespace fixes Remove trailing whitespaces. Many editors remove them automatically or handle them differently. This makes working with the code much easier. --- design/dbg/dbg.sv | 272 +++--- design/dec/cdecode | 68 +- design/dec/csrdecode | 48 +- design/dec/dec.sv | 226 ++--- design/dec/dec_decode_ctl.sv | 1240 ++++++++++++++-------------- design/dec/dec_gpr_ctl.sv | 44 +- design/dec/dec_ib_ctl.sv | 196 ++--- design/dec/dec_tlu_ctl.sv | 668 +++++++-------- design/dec/dec_trigger.sv | 22 +- design/dec/decode | 44 +- design/dma_ctrl.sv | 130 +-- design/dmi/dmi_jtag_to_core_sync.v | 458 +++++----- design/dmi/dmi_wrapper.v | 240 +++--- design/dmi/double_flop_sync.v | 104 +-- design/dmi/rvjtag_tap.sv | 34 +- design/dmi/toggle_sync.v | 138 ++-- design/exu/exu.sv | 56 +- design/exu/exu_alu_ctl.sv | 74 +- design/exu/exu_div_ctl.sv | 54 +- design/exu/exu_mul_ctl.sv | 8 +- design/flist.vcs | 68 +- design/flist.vlog | 68 +- design/ifu/ifu.sv | 134 +-- design/ifu/ifu_aln_ctl.sv | 528 ++++++------ design/ifu/ifu_bp_ctl.sv | 552 ++++++------- design/ifu/ifu_compress_ctl.sv | 86 +- design/ifu/ifu_ic_mem.sv | 274 +++--- design/ifu/ifu_iccm_mem.sv | 52 +- design/ifu/ifu_ifc_ctl.sv | 84 +- design/ifu/ifu_mem_ctl.sv | 568 ++++++------- design/include/build.h | 6 +- design/include/global.h | 12 +- design/lib/ahb_to_axi4.sv | 102 +-- design/lib/axi4_to_ahb.sv | 130 +-- design/lib/beh_lib.sv | 160 ++-- design/lib/mem_lib.sv | 276 +++---- design/lsu/lsu.sv | 120 +-- design/lsu/lsu_addrcheck.sv | 60 +- design/lsu/lsu_bus_intf.sv | 84 +- design/lsu/lsu_bus_read_buffer.sv | 118 +-- design/lsu/lsu_bus_write_buffer.sv | 106 +-- design/lsu/lsu_clkdomain.sv | 86 +- design/lsu/lsu_dccm_ctl.sv | 66 +- design/lsu/lsu_dccm_mem.sv | 58 +- design/lsu/lsu_ecc.sv | 74 +- design/lsu/lsu_lsc_ctl.sv | 128 +-- design/lsu/lsu_stbuf.sv | 87 +- design/lsu/lsu_trigger.sv | 22 +- design/mem.sv | 42 +- design/pic_ctrl.sv | 172 ++-- design/swerv.sv | 460 +++++------ design/swerv_wrapper.sv | 106 +-- 52 files changed, 4506 insertions(+), 4507 deletions(-) diff --git a/design/dbg/dbg.sv b/design/dbg/dbg.sv index cc0e85a..a88c152 100644 --- a/design/dbg/dbg.sv +++ b/design/dbg/dbg.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,21 +16,21 @@ // $Id$ // // Function: Top level SWERV core file to control the debug mode -// Comments: Responsible to put the rest of the core in quiesce mode, +// Comments: Responsible to put the rest of the core in quiesce mode, // Send the commands/address. sends WrData and Recieve read Data. -// And then Resume the core to do the normal mode -// Author : +// And then Resume the core to do the normal mode +// Author : //******************************************************************************** module dbg ( // outputs to the core for command and data interface output logic [31:0] dbg_cmd_addr, output logic [31:0] dbg_cmd_wrdata, - output logic dbg_cmd_valid, + output logic dbg_cmd_valid, output logic dbg_cmd_write, // 1: write command, 0: read_command - output logic [1:0] dbg_cmd_type, // 0:gpr 1:csr 2: memory + output logic [1:0] dbg_cmd_type, // 0:gpr 1:csr 2: memory output logic [1:0] dbg_cmd_size, // size of the abstract mem access debug command output logic dbg_core_rst_l, // core reset from dm - + // inputs back from the core/dec input logic [31:0] core_dbg_rddata, input logic core_dbg_cmd_done, // This will be treated like a valid signal @@ -39,24 +39,24 @@ module dbg ( // Signals to dma to get a bubble output logic dbg_dma_bubble, // Debug needs a bubble to send a valid input logic dma_dbg_ready, // DMA is ready to accept debug request - + // interface with the rest of the core to halt/resume handshaking output logic dbg_halt_req, // This is a pulse output logic dbg_resume_req, // Debug sends a resume requests. Pulse input logic dec_tlu_debug_mode, // Core is in debug mode - input logic dec_tlu_dbg_halted, // The core has finished the queiscing sequence. Core is halted now + input logic dec_tlu_dbg_halted, // The core has finished the queiscing sequence. Core is halted now input logic dec_tlu_resume_ack, // core sends back an ack for the resume (pulse) - + // inputs from the JTAG input logic dmi_reg_en, // read or write input logic [31:0] dmi_reg_addr, // address of DM register input logic dmi_reg_wr_en, // write instruction input logic [31:0] dmi_reg_wdata, // write data - // output + // output output logic [31:0] dmi_reg_rdata, // read data - output logic dmi_reg_ack, + output logic dmi_reg_ack, - // AXI signals + // AXI signals // AXI Write Channels output logic sb_axi_awvalid, input logic sb_axi_awready, @@ -70,19 +70,19 @@ module dbg ( output logic [3:0] sb_axi_awcache, output logic [2:0] sb_axi_awprot, output logic [3:0] sb_axi_awqos, - - output logic sb_axi_wvalid, + + output logic sb_axi_wvalid, input logic sb_axi_wready, output logic [63:0] sb_axi_wdata, output logic [7:0] sb_axi_wstrb, output logic sb_axi_wlast, - + input logic sb_axi_bvalid, output logic sb_axi_bready, input logic [1:0] sb_axi_bresp, input logic [`RV_SB_BUS_TAG-1:0] sb_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic sb_axi_arvalid, input logic sb_axi_arready, output logic [`RV_SB_BUS_TAG-1:0] sb_axi_arid, @@ -95,17 +95,17 @@ module dbg ( output logic [3:0] sb_axi_arcache, output logic [2:0] sb_axi_arprot, output logic [3:0] sb_axi_arqos, - + input logic sb_axi_rvalid, output logic sb_axi_rready, input logic [`RV_SB_BUS_TAG-1:0] sb_axi_rid, input logic [63:0] sb_axi_rdata, input logic [1:0] sb_axi_rresp, input logic sb_axi_rlast, - + input logic dbg_bus_clk_en, - - // general inputs + + // general inputs input logic clk, input logic free_clk, input logic rst_l, @@ -114,26 +114,26 @@ module dbg ( ); `include "global.h" - + typedef enum logic [2:0] {IDLE=3'b000, HALTING=3'b001, HALTED=3'b010, CMD_START=3'b011, CMD_WAIT=3'b100, CMD_DONE=3'b101, RESUMING=3'b110} state_t; typedef enum logic [3:0] {SBIDLE=4'b0, WAIT=4'b1, CMD_RD=4'b10, CMD_WR=4'b11, CMD_WR_ADDR=4'b100, CMD_WR_DATA=4'b101, RSP_RD=4'b110, RSP_WR=4'b111, DONE=4'b1000} sb_state_t; - - state_t dbg_state; + + state_t dbg_state; state_t dbg_nxtstate; logic dbg_state_en; // these are the registers that the debug module implements logic [31:0] dmstatus_reg; // [26:24]-dmerr, [17:16]-resume ack, [9:8]-halted, [3:0]-version logic [31:0] dmcontrol_reg; // dmcontrol register has only 6 bits implemented. 31: haltreq, 30: resumereq, 29: haltreset, 28: ackhavereset, 1: ndmreset, 0: dmactive. - logic [31:0] command_reg; + logic [31:0] command_reg; logic [31:0] abstractcs_reg; // bits implemted are [12] - busy and [10:8]= command error logic [31:0] haltsum0_reg; logic [31:0] data0_reg; logic [31:0] data1_reg; - // data 0 + // data 0 logic [31:0] data0_din; - logic data0_reg_wren, data0_reg_wren0, data0_reg_wren1; - // data 1 + logic data0_reg_wren, data0_reg_wren0, data0_reg_wren1; + // data 1 logic [31:0] data1_din; logic data1_reg_wren, data1_reg_wren0, data1_reg_wren1; // abstractcs @@ -159,34 +159,34 @@ module dbg ( logic command_wren; // needed to send the read data back for dmi reads logic [31:0] dmi_reg_rdata_din; - + sb_state_t sb_state; sb_state_t sb_nxtstate; logic sb_state_en; //System bus section - logic sbcs_wren; + logic sbcs_wren; logic sbcs_sbbusy_wren; logic sbcs_sbbusy_din; logic sbcs_sbbusyerror_wren; logic sbcs_sbbusyerror_din; - + logic sbcs_sberror_wren; logic [2:0] sbcs_sberror_din; logic sbcs_unaligned; logic sbcs_illegal_size; - + // data logic sbdata0_reg_wren0; - logic sbdata0_reg_wren1; + logic sbdata0_reg_wren1; logic sbdata0_reg_wren; logic [31:0] sbdata0_din; - + logic sbdata1_reg_wren0; - logic sbdata1_reg_wren1; + logic sbdata1_reg_wren1; logic sbdata1_reg_wren; logic [31:0] sbdata1_din; - + logic sbaddress0_reg_wren0; logic sbaddress0_reg_wren1; logic sbaddress0_reg_wren; @@ -195,7 +195,7 @@ module dbg ( logic sbreadonaddr_access; logic sbreadondata_access; logic sbdata0wr_access; - + logic sb_axi_awvalid_q, sb_axi_awready_q; logic sb_axi_wvalid_q, sb_axi_wready_q; logic sb_axi_arvalid_q, sb_axi_arready_q; @@ -203,7 +203,7 @@ module dbg ( logic sb_axi_rvalid_q, sb_axi_rready_q; logic [1:0] sb_axi_bresp_q, sb_axi_rresp_q; logic [63:0] sb_axi_rdata_q; - + logic [63:0] sb_bus_rdata; //registers @@ -211,23 +211,23 @@ module dbg ( logic [31:0] sbaddress0_reg; logic [31:0] sbdata0_reg; logic [31:0] sbdata1_reg; - + logic dbg_dm_rst_l; //clken logic dbg_free_clken; logic dbg_free_clk; - + logic sb_free_clken; logic sb_free_clk; - + logic bus_clken; logic bus_clk; - + // clocking - // used for the abstract commands. + // used for the abstract commands. assign dbg_free_clken = dmi_reg_en | dmi_reg_ack | (dbg_state != IDLE) | dbg_state_en | dec_tlu_dbg_halted | clk_override; - + // used for the system bus assign sb_free_clken = dmi_reg_en | sb_state_en | (sb_state != SBIDLE) | clk_override; assign bus_clken = (sb_axi_awvalid | sb_axi_wvalid | sb_axi_arvalid | sb_axi_bvalid | sb_axi_rvalid | clk_override) & dbg_bus_clk_en; @@ -235,32 +235,32 @@ module dbg ( rvclkhdr dbg_free_cgc (.en(dbg_free_clken), .l1clk(dbg_free_clk), .*); rvclkhdr sb_free_cgc (.en(sb_free_clken), .l1clk(sb_free_clk), .*); rvclkhdr bus_cgc (.en(bus_clken), .l1clk(bus_clk), .*); - - // end clocking section - + + // end clocking section + // Reset logic assign dbg_dm_rst_l = rst_l & (dmcontrol_reg[0] | scan_mode); - assign dbg_core_rst_l = ~dmcontrol_reg[1]; - + assign dbg_core_rst_l = ~dmcontrol_reg[1]; + // 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 assign sbcs_reg[31:29] = 3'b1; assign sbcs_reg[28:23] = '0; assign sbcs_reg[11:5] = 7'h20; - assign sbcs_reg[4:0] = 5'b01111; + assign sbcs_reg[4:0] = 5'b01111; assign sbcs_wren = (dmi_reg_addr[31:0] == 32'h38) & dmi_reg_en & dmi_reg_wr_en & (sb_state == SBIDLE); // & (sbcs_reg[14:12] == 3'b000); assign sbcs_sbbusyerror_wren = (sbcs_wren & dmi_reg_wdata[22]) | ((sb_state != SBIDLE) & dmi_reg_en & ((dmi_reg_addr[31:0] == 32'h39) | (dmi_reg_addr[31:0] == 32'h3c) | (dmi_reg_addr[31:0] == 32'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:15]), .dout(sbcs_reg[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])) | + + assign sbcs_unaligned = ((sbcs_reg[19:17] == 3'b001) & sbaddress0_reg[0]) | + ((sbcs_reg[19:17] == 3'b010) & (|sbaddress0_reg[1:0])) | ((sbcs_reg[19:17] == 3'b011) & (|sbaddress0_reg[2:0])); assign sbcs_illegal_size = sbcs_reg[19]; // Anything bigger than 64 bits is illegal @@ -269,35 +269,35 @@ module dbg ( ({4{(sbcs_reg[19:17] == 3'b001)}} & 4'b0010) | ({4{(sbcs_reg[19:17] == 3'b010)}} & 4'b0100) | ({4{(sbcs_reg[19:17] == 3'b100)}} & 4'b1000); - - // sbdata + + // sbdata //assign sbdata0_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr[31:0] == 32'h3c); assign sbdata0_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr[31:0] == 32'h3c); // write data only when single read is 0 - assign sbdata0_reg_wren1 = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren; + assign sbdata0_reg_wren1 = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren; assign sbdata0_reg_wren = sbdata0_reg_wren0 | sbdata0_reg_wren1; - + assign sbdata1_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr[31:0] == 32'h3d); // write data only when single read is 0; - assign sbdata1_reg_wren1 = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren; + assign sbdata1_reg_wren1 = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren; assign sbdata1_reg_wren = sbdata1_reg_wren0 | sbdata1_reg_wren1; - + assign sbdata0_din[31:0] = ({32{sbdata0_reg_wren0}} & dmi_reg_wdata[31:0]) | ({32{sbdata0_reg_wren1}} & sb_bus_rdata[31:0]); 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)); - + // sbaddress assign sbaddress0_reg_wren0 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr[31:0] == 32'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]})); + ({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)); - + assign sbreadonaddr_access = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr[31:0] == 32'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[31:0] == 32'h3c) & sbcs_reg[15]; // if readondata is set the next command will start upon reading of data0 - assign sbdata0wr_access = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr[31:0] == 32'h3c); // write to sbdata0 will start write command to system bus + assign sbdata0wr_access = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr[31:0] == 32'h3c); // write to sbdata0 will start write command to system bus // memory mapped registers // dmcontrol register has only 6 bits implemented. 31: haltreq, 30: resumereq, 29: haltreset, 28: ackhavereset, 1: ndmreset, 0: dmactive. @@ -308,7 +308,7 @@ module dbg ( rvdffs #(5) dmcontrolff (.din({dmi_reg_wdata[31:28],dmi_reg_wdata[1]}), .dout({dmcontrol_reg[31: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(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 // rest all the bits are zeroed out @@ -327,11 +327,11 @@ module dbg ( assign dmstatus_havereset_wren = (dmi_reg_addr[31:0] == 32'h10) & dmi_reg_wdata[1] & dmi_reg_en & dmi_reg_wr_en; assign dmstatus_havereset_rst = (dmi_reg_addr[31:0] == 32'h10) & dmi_reg_wdata[28] & dmi_reg_en & dmi_reg_wr_en; - + 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), .dout(dmstatus_halted), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); rvdffsc #(1) dmstatus_havereset_reg (.din(1'b1), .dout(dmstatus_havereset), .en(dmstatus_havereset_wren), .clear(dmstatus_havereset_rst), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); - + // haltsum0 register assign haltsum0_reg[31:1] = '0; assign haltsum0_reg[0] = dmstatus_halted; @@ -342,37 +342,37 @@ module dbg ( assign abstractcs_reg[11] = '0; assign abstractcs_reg[7:4] = '0; assign abstractcs_reg[3:0] = 4'h2; // One data register - assign abstractcs_error_sel0 = abstractcs_reg[12] & dmi_reg_en & ((dmi_reg_wr_en & ( (dmi_reg_addr[31:0] == 32'h16) | (dmi_reg_addr[31:0] == 32'h17))) | (dmi_reg_addr[31:0] == 32'h4)); + assign abstractcs_error_sel0 = abstractcs_reg[12] & dmi_reg_en & ((dmi_reg_wr_en & ( (dmi_reg_addr[31:0] == 32'h16) | (dmi_reg_addr[31:0] == 32'h17))) | (dmi_reg_addr[31:0] == 32'h4)); assign abstractcs_error_sel1 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr[31:0] == 32'h17) & ~((dmi_reg_wdata[31:24] == 8'b0) | (dmi_reg_wdata[31:24] == 8'h2)); assign abstractcs_error_sel2 = core_dbg_cmd_done & core_dbg_cmd_fail; assign abstractcs_error_sel3 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr[31:0] == 32'h17) & (dbg_state != HALTED); - assign abstractcs_error_sel4 = (dmi_reg_addr[31:0] == 32'h17) & dmi_reg_en & dmi_reg_wr_en & - ( ((dmi_reg_wdata[22:20] == 3'b001) & data1_reg[0]) | - ((dmi_reg_wdata[22:20] == 3'b010) & (|data1_reg[1:0])) | + assign abstractcs_error_sel4 = (dmi_reg_addr[31:0] == 32'h17) & dmi_reg_en & dmi_reg_wr_en & + ( ((dmi_reg_wdata[22:20] == 3'b001) & data1_reg[0]) | + ((dmi_reg_wdata[22:20] == 3'b010) & (|data1_reg[1:0])) | dmi_reg_wdata[22] | (dmi_reg_wdata[22:20] == 3'b011) ); - + assign abstractcs_error_sel5 = (dmi_reg_addr[31:0] == 32'h16) & dmi_reg_en & dmi_reg_wr_en; - + assign abstractcs_error_selor = abstractcs_error_sel0 | abstractcs_error_sel1 | abstractcs_error_sel2 | abstractcs_error_sel3 | abstractcs_error_sel4 | abstractcs_error_sel5; - - assign abstractcs_error_din[2:0] = ({3{abstractcs_error_sel0}} & 3'b001) | // writing command or abstractcs while a command was executing. Or accessing data0 + + assign abstractcs_error_din[2:0] = ({3{abstractcs_error_sel0}} & 3'b001) | // writing command or abstractcs while a command was executing. Or accessing data0 ({3{abstractcs_error_sel1}} & 3'b010) | // writing a non-zero command to cmd field of command ({3{abstractcs_error_sel2}} & 3'b011) | // exception while running command ({3{abstractcs_error_sel3}} & 3'b100) | // writing a comnand when not in the halted state ({3{abstractcs_error_sel4}} & 3'b111) | // unaligned abstract memory command ({3{abstractcs_error_sel5}} & ~dmi_reg_wdata[10:8] & abstractcs_reg[10:8]) | // W1C ({3{~abstractcs_error_selor}} & 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)); - - + + // command register - implemented all the bits in this register // command[16] = 1: write, 0: read assign command_wren = (dmi_reg_addr[31:0] == 32'h17) & dmi_reg_en & dmi_reg_wr_en & (dbg_state == HALTED); rvdffe #(32) dmcommand_reg (.*, .din(dmi_reg_wdata[31:0]), .dout(command_reg[31:0]), .en(command_wren), .rst_l(dbg_dm_rst_l)); - + // data0 reg assign data0_reg_wren0 = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr[31:0] == 32'h4) & (dbg_state == HALTED)); assign data0_reg_wren1 = core_dbg_cmd_done & (dbg_state == CMD_WAIT) & ~command_reg[16]; @@ -380,17 +380,17 @@ module dbg ( assign data0_din[31:0] = ({32{data0_reg_wren0}} & dmi_reg_wdata[31:0]) | ({32{data0_reg_wren1}} & core_dbg_rddata[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)); - // data 1 + // data 1 assign data1_reg_wren0 = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr[31:0] == 32'h5) & (dbg_state == HALTED)); assign data1_reg_wren1 = 1'b0; // core_dbg_cmd_done & (dbg_state == CMD_WAIT) & ~command_reg[16]; assign data1_reg_wren = data1_reg_wren0 | data1_reg_wren1; - + assign data1_din[31:0] = ({32{data1_reg_wren0}} & dmi_reg_wdata[31:0]); //({32{data0_reg_wren1}} & core_dbg_rddata[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)); @@ -402,11 +402,11 @@ module dbg ( abstractcs_busy_din = 1'b0; dbg_halt_req = 1'b0; // single pulse output to the core dbg_resume_req = 1'b0; // single pulse output to the core - + case (dbg_state) IDLE: begin dbg_nxtstate = dmstatus_reg[9] ? HALTED : HALTING; // initiate the halt command to the core - dbg_state_en = ((dmcontrol_reg[31] & ~dec_tlu_debug_mode) | dmstatus_reg[9]) & ~dmcontrol_reg[1]; // when the jtag writes the halt bit in the DM register, OR when the status indicates Halted + dbg_state_en = ((dmcontrol_reg[31] & ~dec_tlu_debug_mode) | dmstatus_reg[9]) & ~dmcontrol_reg[1]; // when the jtag writes the halt bit in the DM register, OR when the status indicates Halted dbg_halt_req = dmcontrol_reg[31] & ~dec_tlu_debug_mode; // only when jtag has written the halt_req bit in the control end HALTING : begin @@ -415,27 +415,27 @@ module dbg ( end HALTED: begin dbg_nxtstate = dmcontrol_reg[1] ? IDLE : (dmcontrol_reg[30] & ~dmcontrol_reg[31]) ? RESUMING : CMD_START; // wait for halted to go away before send to resume. Else start of new command - dbg_state_en = (dmcontrol_reg[30] & ~dmcontrol_reg[31] & dmcontrol_wren_Q) | command_wren | dmcontrol_reg[1]; // need to be exclusive ??? + dbg_state_en = (dmcontrol_reg[30] & ~dmcontrol_reg[31] & dmcontrol_wren_Q) | command_wren | dmcontrol_reg[1]; // need to be exclusive ??? abstractcs_busy_wren = dbg_state_en & (dbg_nxtstate == CMD_START); // write busy when a new command was written by jtag - abstractcs_busy_din = 1'b1; - dbg_resume_req = dbg_state_en & (dbg_nxtstate == RESUMING); // single cycle pulse to core if resuming + abstractcs_busy_din = 1'b1; + dbg_resume_req = dbg_state_en & (dbg_nxtstate == RESUMING); // single cycle pulse to core if resuming end CMD_START: begin - dbg_nxtstate = (|abstractcs_reg[10:8]) ? CMD_DONE : CMD_WAIT; // new command sent to the core - dbg_state_en = dbg_cmd_valid | (|abstractcs_reg[10:8]); - end + dbg_nxtstate = (|abstractcs_reg[10:8]) ? CMD_DONE : CMD_WAIT; // new command sent to the core + dbg_state_en = dbg_cmd_valid | (|abstractcs_reg[10:8]); + end CMD_WAIT: begin - dbg_nxtstate = CMD_DONE; + dbg_nxtstate = CMD_DONE; dbg_state_en = core_dbg_cmd_done; // go to done state for one cycle after completing current command end CMD_DONE: begin - dbg_nxtstate = HALTED; + dbg_nxtstate = HALTED; dbg_state_en = 1'b1; abstractcs_busy_wren = dbg_state_en; // remove the busy bit from the abstracts ( bit 12 ) abstractcs_busy_din = 1'b0; end RESUMING : begin - dbg_nxtstate = IDLE; + dbg_nxtstate = IDLE; dbg_state_en = dmstatus_reg[17]; // resume ack has been updated in the dmstatus register end default : begin @@ -451,33 +451,33 @@ module dbg ( assign dmi_reg_rdata_din[31:0] = ({32{dmi_reg_addr[31:0] == 32'h4}} & data0_reg[31:0]) | ({32{dmi_reg_addr[31:0] == 32'h5}} & data1_reg[31:0]) | - ({32{dmi_reg_addr[31:0] == 32'h10}} & dmcontrol_reg[31:0]) | + ({32{dmi_reg_addr[31:0] == 32'h10}} & dmcontrol_reg[31:0]) | ({32{dmi_reg_addr[31:0] == 32'h11}} & dmstatus_reg[31:0]) | - ({32{dmi_reg_addr[31:0] == 32'h16}} & abstractcs_reg[31:0]) | + ({32{dmi_reg_addr[31:0] == 32'h16}} & abstractcs_reg[31:0]) | ({32{dmi_reg_addr[31:0] == 32'h17}} & command_reg[31:0]) | ({32{dmi_reg_addr[31:0] == 32'h40}} & haltsum0_reg[31:0]) | ({32{dmi_reg_addr[31:0] == 32'h38}} & sbcs_reg[31:0]) | - ({32{dmi_reg_addr[31:0] == 32'h39}} & sbaddress0_reg[31:0]) | - ({32{dmi_reg_addr[31:0] == 32'h3c}} & sbdata0_reg[31:0]) | + ({32{dmi_reg_addr[31:0] == 32'h39}} & sbaddress0_reg[31:0]) | + ({32{dmi_reg_addr[31:0] == 32'h3c}} & sbdata0_reg[31:0]) | ({32{dmi_reg_addr[31:0] == 32'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), .clk(dbg_free_clk)); // Ack will use the power on reset only otherwise there won't be any ack until dmactive is 1 rvdff #(1) dmi_ack_reg (.din(dmi_reg_en), .dout(dmi_reg_ack), .rst_l(rst_l), .clk(free_clk)); rvdff #(32) dmi_rddata_reg (.din(dmi_reg_rdata_din[31:0]), .dout(dmi_reg_rdata[31:0]), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk)); - + // interface for the core assign dbg_cmd_addr[31:0] = (command_reg[31:24] == 8'h2) ? {data1_reg[31:2],2'b0} : {20'b0, command_reg[11:0]}; // Only word addresses for abstract memory assign dbg_cmd_wrdata[31:0] = data0_reg[31:0]; - assign dbg_cmd_valid = (dbg_state == CMD_START) & ~(|abstractcs_reg[10:8]) & dma_dbg_ready; + assign dbg_cmd_valid = (dbg_state == CMD_START) & ~(|abstractcs_reg[10:8]) & dma_dbg_ready; assign dbg_cmd_write = command_reg[16]; assign dbg_cmd_type[1:0] = (command_reg[31:24] == 8'h2) ? 2'b10 : {1'b0, (command_reg[15:12] == 4'b0)}; assign dbg_cmd_size[1:0] = command_reg[21:20]; // Ask DMA to stop taking bus trxns since debug request is done assign dbg_dma_bubble = ((dbg_state == CMD_START) & ~(|abstractcs_reg[10:8])) | (dbg_state == CMD_WAIT); - + // system bus FSM always_comb begin sb_nxtstate = SBIDLE; @@ -486,7 +486,7 @@ module dbg ( sbcs_sbbusy_din = 1'b0; sbcs_sberror_wren = 1'b0; sbcs_sberror_din[2:0] = 3'b0; - sbaddress0_reg_wren1 = 1'b0; + sbaddress0_reg_wren1 = 1'b0; case (sb_state) SBIDLE: begin sb_nxtstate = WAIT; @@ -495,62 +495,62 @@ module dbg ( sbcs_sbbusy_din = 1'b1; sbcs_sberror_wren = sbcs_wren & (|dmi_reg_wdata[14:12]); // write to clear the error bits sbcs_sberror_din[2:0] = ~dmi_reg_wdata[14:12] & sbcs_reg[14:12]; - end + end WAIT: begin sb_nxtstate = (sbcs_unaligned | sbcs_illegal_size) ? DONE : (sbcs_reg[15] | sbcs_reg[20]) ? CMD_RD : CMD_WR; sb_state_en = dbg_bus_clk_en | sbcs_unaligned | sbcs_illegal_size; sbcs_sberror_wren = sbcs_unaligned | sbcs_illegal_size; sbcs_sberror_din[2:0] = sbcs_unaligned ? 3'b011 : 3'b100; end - CMD_RD : begin - sb_nxtstate = RSP_RD; + CMD_RD : begin + sb_nxtstate = RSP_RD; sb_state_en = sb_axi_arvalid_q & sb_axi_arready_q & dbg_bus_clk_en; - end - CMD_WR : begin - sb_nxtstate = (sb_axi_awready_q & sb_axi_wready_q) ? RSP_WR : (sb_axi_awready_q ? CMD_WR_DATA : CMD_WR_ADDR); + end + CMD_WR : begin + sb_nxtstate = (sb_axi_awready_q & sb_axi_wready_q) ? RSP_WR : (sb_axi_awready_q ? CMD_WR_DATA : CMD_WR_ADDR); sb_state_en = ((sb_axi_awvalid_q & sb_axi_awready_q) | (sb_axi_wvalid_q & sb_axi_wready_q)) & dbg_bus_clk_en; - end - CMD_WR_ADDR : begin - sb_nxtstate = RSP_WR; + end + CMD_WR_ADDR : begin + sb_nxtstate = RSP_WR; sb_state_en = sb_axi_awvalid_q & sb_axi_awready_q & dbg_bus_clk_en; - end - CMD_WR_DATA : begin - sb_nxtstate = RSP_WR; + end + CMD_WR_DATA : begin + sb_nxtstate = RSP_WR; sb_state_en = sb_axi_wvalid_q & sb_axi_wready_q & dbg_bus_clk_en; - end - RSP_RD: begin + end + RSP_RD: begin sb_nxtstate = DONE; sb_state_en = sb_axi_rvalid_q & sb_axi_rready_q & dbg_bus_clk_en; sbcs_sberror_wren = sb_state_en & sb_axi_rresp_q[1]; sbcs_sberror_din[2:0] = 3'b010; - end - RSP_WR: begin + end + RSP_WR: begin sb_nxtstate = DONE; sb_state_en = sb_axi_bvalid_q & sb_axi_bready_q & dbg_bus_clk_en; sbcs_sberror_wren = sb_state_en & sb_axi_bresp_q[1]; sbcs_sberror_din[2:0] = 3'b010; - end - DONE: begin + end + DONE: begin sb_nxtstate = SBIDLE; sb_state_en = 1'b1; sbcs_sbbusy_wren = 1'b1; // reset the single read sbcs_sbbusy_din = 1'b0; - sbaddress0_reg_wren1 = sbcs_reg[16]; // auto increment was set. Update to new address after completing the current command + sbaddress0_reg_wren1 = sbcs_reg[16]; // auto increment was set. Update to new address after completing the current command end - default : begin + default : begin sb_nxtstate = SBIDLE; sb_state_en = 1'b0; sbcs_sbbusy_wren = 1'b0; sbcs_sbbusy_din = 1'b0; sbcs_sberror_wren = 1'b0; sbcs_sberror_din[2:0] = 3'b0; - sbaddress0_reg_wren1 = 1'b0; - end + sbaddress0_reg_wren1 = 1'b0; + end 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)); - + //rvdff #(.WIDTH(1)) bus_clken_ff (.din(dbg_bus_clk_en), .dout(dbg_bus_clk_en_q), .rst_l(dbg_dm_rst_l), .clk(dbg_sb_c2_free_clk), .*); rvdffs #(.WIDTH(1)) axi_awvalid_ff (.din(sb_axi_awvalid), .dout(sb_axi_awvalid_q), .en(dbg_bus_clk_en), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk), .*); @@ -580,7 +580,7 @@ module dbg ( assign sb_axi_awburst[1:0] = 2'b01; assign sb_axi_awqos[3:0] = '0; assign sb_axi_awlock = '0; - + assign sb_axi_wvalid = ((sb_state == CMD_WR) | (sb_state == CMD_WR_DATA)) & ~(sb_axi_wvalid_q & sb_axi_wready_q); assign sb_axi_wdata[63:0] = ({64{(sbcs_reg[19:17] == 3'h0)}} & {8{sbdata0_reg[7:0]}}) | ({64{(sbcs_reg[19:17] == 3'h1)}} & {4{sbdata0_reg[15:0]}}) | @@ -612,10 +612,10 @@ module dbg ( ({64{sbcs_reg[19:17] == 3'h1}} & ((sb_axi_rdata_q[63:0] >> 16*sbaddress0_reg[2:1]) & 64'hffff)) | ({64{sbcs_reg[19:17] == 3'h2}} & ((sb_axi_rdata_q[63:0] >> 32*sbaddress0_reg[2]) & 64'hffff_ffff)) | ({64{sbcs_reg[19:17] == 3'h3}} & sb_axi_rdata_q[63:0]); - + `ifdef ASSERT_ON -// assertion. -// when the resume_ack is asserted then the dec_tlu_dbg_halted should be 0 +// assertion. +// when the resume_ack is asserted then the dec_tlu_dbg_halted should be 0 dm_check_resume_and_halted: assert property (@(posedge clk) disable iff(~rst_l) (~dec_tlu_resume_ack | ~dec_tlu_dbg_halted)); `endif endmodule diff --git a/design/dec/cdecode b/design/dec/cdecode index 52b3dd3..2f9202f 100644 --- a/design/dec/cdecode +++ b/design/dec/cdecode @@ -116,7 +116,7 @@ c.swsp = [110...........10] c.xor = [100011...01...01] -.input +.input rv32c = { i[15] i[14] @@ -159,38 +159,38 @@ rv32c = { uimm5_0 uswimm6_2 uswspimm7_2 - o[31] - o[30] - o[29] - o[28] - o[27] - o[26] - o[25] - o[24] - o[23] - o[22] - o[21] - o[20] - o[19] - o[18] - o[17] - o[16] - o[15] - o[14] - o[13] - o[12] - o[11] - o[10] - o[9] - o[8] - o[7] - o[6] - o[5] - o[4] - o[3] - o[2] - o[1] - o[0] + o[31] + o[30] + o[29] + o[28] + o[27] + o[26] + o[25] + o[24] + o[23] + o[22] + o[21] + o[20] + o[19] + o[18] + o[17] + o[16] + o[15] + o[14] + o[13] + o[12] + o[11] + o[10] + o[9] + o[8] + o[7] + o[6] + o[5] + o[4] + o[3] + o[2] + o[1] + o[0] } # assign rs2d[4:0] = i[6:2]; @@ -199,7 +199,7 @@ rv32c = { # # assign rdpd[4:0] = {2'b01, i[9:7]}; # -# assign rs2pd[4:0] = {2'b01, i[4:2]}; +# assign rs2pd[4:0] = {2'b01, i[4:2]}; .decode diff --git a/design/dec/csrdecode b/design/dec/csrdecode index 4544cdd..84146ae 100644 --- a/design/dec/csrdecode +++ b/design/dec/csrdecode @@ -67,7 +67,7 @@ csr_perfvg = [001100100111] csr_perfvh = [001100101...] csr_perfvi = [00110011....] -.input +.input csr = { dec_csr_rdaddr_d[11] @@ -87,23 +87,23 @@ csr = { .output csr = { - csr_misa - csr_mvendorid - csr_marchid - csr_mimpid - csr_mhartid - csr_mstatus - csr_mtvec - csr_mip - csr_mie - csr_mcyclel - csr_mcycleh - csr_minstretl - csr_minstreth - csr_mscratch - csr_mepc - csr_mcause - csr_mtval + csr_misa + csr_mvendorid + csr_marchid + csr_mimpid + csr_mhartid + csr_mstatus + csr_mtvec + csr_mip + csr_mie + csr_mcyclel + csr_mcycleh + csr_minstretl + csr_minstreth + csr_mscratch + csr_mepc + csr_mcause + csr_mtval csr_mrac csr_dmst csr_mdeau @@ -120,8 +120,8 @@ csr = { csr_mcpc csr_mfdc csr_dpc - csr_mtsel - csr_mtdata1 + csr_mtsel + csr_mtdata1 csr_mtdata2 csr_mhpmc3 csr_mhpmc4 @@ -211,10 +211,10 @@ csr[ csr_mhpme6 ] = { csr_mhpme6 } csr[ csr_micect ] = { csr_micect } csr[ csr_miccmect ] = { csr_miccmect } csr[ csr_mdccmect ] = { csr_mdccmect } -csr[ csr_dicawics ] = { csr_dicawics } -csr[ csr_dicad0 ] = { csr_dicad0 } -csr[ csr_dicad1 ] = { csr_dicad1 } -csr[ csr_dicago ] = { csr_dicago } +csr[ csr_dicawics ] = { csr_dicawics } +csr[ csr_dicad0 ] = { csr_dicad0 } +csr[ csr_dicad1 ] = { csr_dicad1 } +csr[ csr_dicago ] = { csr_dicago } csr[ csr_perfva ] = { valid_only } csr[ csr_perfvb ] = { valid_only } diff --git a/design/dec/dec.sv b/design/dec/dec.sv index f06ca6d..352f62d 100644 --- a/design/dec/dec.sv +++ b/design/dec/dec.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -14,19 +14,19 @@ // limitations under the License. // dec: decode unit - decode, bypassing, ARF, interrupts -// +// //******************************************************************************** // $Id$ // -// -// Function: Decode +// +// Function: Decode // Comments: Decode, dependency scoreboard, ARF // -// +// // A -> D -> EX1 ... WB -// +// //******************************************************************************** - + module dec import swerv_types::*; ( @@ -36,12 +36,12 @@ module dec output logic dec_pause_state, // to top for active state clock gating - + input logic rst_l, // reset, active low input logic [31:1] rst_vec, // reset vector, from core pins input logic nmi_int, // NMI pin - input logic [31:1] nmi_vec, // NMI vector, from pins + input logic [31:1] nmi_vec, // NMI vector, from pins input logic i_cpu_halt_req, // Asynchronous Halt request to CPU input logic i_cpu_run_req, // Asynchronous Restart request to CPU @@ -51,40 +51,40 @@ module dec output logic o_cpu_run_ack, // Run request ack output logic o_debug_mode_status, // Core to the PMU that core is in debug mode. When core is in debug mode, the PMU should refrain from sendng a halt or run request - - output logic dec_ib0_valid_eff_d, // effective valid taking decode into account + + output logic dec_ib0_valid_eff_d, // effective valid taking decode into account output logic dec_ib1_valid_eff_d, input logic exu_pmu_i0_br_misp, // slot 0 branch misp input logic exu_pmu_i0_br_ataken, // slot 0 branch actual taken - input logic exu_pmu_i0_pc4, // slot 0 4 byte branch - input logic exu_pmu_i1_br_misp, // slot 1 branch misp + input logic exu_pmu_i0_pc4, // slot 0 4 byte branch + input logic exu_pmu_i1_br_misp, // slot 1 branch misp input logic exu_pmu_i1_br_ataken, // slot 1 branch actual taken - input logic exu_pmu_i1_pc4, // slot 1 4 byte branch + input logic exu_pmu_i1_pc4, // slot 1 4 byte branch - input logic lsu_nonblock_load_valid_dc3, // valid nonblock load at dc3 - input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // -> corresponding tag - input logic lsu_nonblock_load_inv_dc5, // invalidate request for nonblock load dc5 - input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // -> corresponding tag - input logic lsu_nonblock_load_data_valid, // valid nonblock load data back - input logic lsu_nonblock_load_data_error, // nonblock load bus error - input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag + input logic lsu_nonblock_load_valid_dc3, // valid nonblock load at dc3 + input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // -> corresponding tag + input logic lsu_nonblock_load_inv_dc5, // invalidate request for nonblock load dc5 + input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // -> corresponding tag + input logic lsu_nonblock_load_data_valid, // valid nonblock load data back + input logic lsu_nonblock_load_data_error, // nonblock load bus error + input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag input logic [31:0] lsu_nonblock_load_data, // nonblock load data - + input logic lsu_pmu_bus_trxn, // D side bus transaction input logic lsu_pmu_bus_misaligned, // D side bus misaligned input logic lsu_pmu_bus_error, // D side bus error input logic lsu_pmu_bus_busy, // D side bus busy input logic lsu_pmu_misaligned_dc3, // D side load or store misaligned - + input logic [1:0] ifu_pmu_instr_aligned, // aligned instructions input logic ifu_pmu_align_stall, // aligner stalled input logic ifu_pmu_fetch_stall, // fetch unit stalled input logic ifu_pmu_ic_miss, // icache miss input logic ifu_pmu_ic_hit, // icache hit input logic ifu_pmu_bus_error, // Instruction side bus error - input logic ifu_pmu_bus_busy, // Instruction side bus busy + input logic ifu_pmu_bus_busy, // Instruction side bus busy input logic ifu_pmu_bus_trxn, // Instruction side bus transaction input logic [3:0] lsu_trigger_match_dc3, @@ -94,27 +94,27 @@ module dec input logic [1:0] dbg_cmd_type, // command type input logic [31:0] dbg_cmd_addr, // command address input logic [1:0] dbg_cmd_wrdata, // command write data, for fence/fence_i - - input logic ifu_i0_icaf, // icache access fault - input logic ifu_i1_icaf, + + input logic ifu_i0_icaf, // icache access fault + input logic ifu_i1_icaf, input logic ifu_i0_icaf_f1, // i0 has access fault on second fetch group - input logic ifu_i1_icaf_f1, - input logic ifu_i0_perr, // icache parity error - input logic ifu_i1_perr, + input logic ifu_i1_icaf_f1, + input logic ifu_i0_perr, // icache parity error + input logic ifu_i1_perr, input logic ifu_i0_sbecc, // icache/iccm single-bit error - input logic ifu_i1_sbecc, + input logic ifu_i1_sbecc, input logic ifu_i0_dbecc, // icache/iccm double-bit error input logic ifu_i1_dbecc, input logic lsu_freeze_dc3, // freeze pipe: decode -> dc3 input logic lsu_idle_any, // lsu idle for fence instructions - + input br_pkt_t i0_brp, // branch packet input br_pkt_t i1_brp, input lsu_error_pkt_t lsu_error_pkt_dc3, // LSU exception/error packet - + input logic lsu_imprecise_error_load_any, // LSU imprecise load bus error input logic lsu_imprecise_error_store_any, // LSU imprecise store bus error input logic [31:0] lsu_imprecise_error_addr_any, // LSU imprecise bus error address @@ -126,7 +126,7 @@ module dec input logic [31:1] exu_i1_flush_path_e4, // slot 1 flush target for mp input logic [15:0] ifu_illegal_inst, // 16b opcode for illegal inst - + input logic exu_div_stall, // stall decode for div executing input logic [31:0] exu_div_result, // final div result input logic exu_div_finish, // cycle div finishes @@ -141,7 +141,7 @@ module dec input logic dma_iccm_stall_any, // iccm stalled, pmu event input logic iccm_dma_sb_error, // ICCM DMA single bit error - + input logic exu_i0_flush_final, // slot0 flush input logic exu_i1_flush_final, // slot1 flush @@ -150,10 +150,10 @@ module dec input logic exu_flush_final, // final flush input logic [31:0] exu_i0_result_e1, // alu result e1 - input logic [31:0] exu_i1_result_e1, + input logic [31:0] exu_i1_result_e1, input logic [31:0] exu_i0_result_e4, // alu result e4 - input logic [31:0] exu_i1_result_e4, + input logic [31:0] exu_i1_result_e4, input logic ifu_i0_valid, ifu_i1_valid, // fetch valids to instruction buffer @@ -161,14 +161,14 @@ module dec input logic [31:1] ifu_i0_pc, ifu_i1_pc, // pc's for instruction buffer input logic ifu_i0_pc4, ifu_i1_pc4, // indication of 4B or 2B for corresponding inst input logic [31:1] exu_i0_pc_e1, // pc's for e1 from the alu's - input logic [31:1] exu_i1_pc_e1, + input logic [31:1] exu_i1_pc_e1, input logic mexintpend, // External interrupt pending input logic timer_int, // Timer interrupt pending (from pin) input logic [7:0] pic_claimid, // PIC claimid input logic [3:0] pic_pl, // PIC priv level - input logic mhwakeup, // High priority wakeup + input logic mhwakeup, // High priority wakeup output logic [3:0] dec_tlu_meicurpl, // to PIC, Current priv level output logic [3:0] dec_tlu_meipt, // to PIC @@ -180,13 +180,13 @@ module dec `endif input logic ifu_ic_debug_rd_data_valid, // diagnostic icache read data valid output cache_debug_pkt_t dec_tlu_ic_diag_pkt, // packet of DICAWICS, DICAD0/1, DICAGO info for icache diagnostics - + // Debug start input logic dbg_halt_req, // DM requests a halt input logic dbg_resume_req, // DM requests a resume input logic ifu_miss_state_idle, // I-side miss buffer empty - + output logic dec_tlu_flush_noredir_wb , // Tell fetch to idle on this flush output logic dec_tlu_dbg_halted, // Core is halted and ready for debug command output logic dec_tlu_pmu_fw_halted, // Core is halted due to Power management unit or firmware halt @@ -195,7 +195,7 @@ module dec output logic dec_tlu_flush_leak_one_wb, // single step output logic dec_tlu_flush_err_wb, // iside perr/ecc rfpc output logic dec_tlu_stall_dma, // stall dma access when there's a halt request - + output logic dec_debug_wdata_rs1_d, // insert debug write data into rs1 at decode output logic [31:0] dec_dbg_rddata, // debug command read data @@ -215,8 +215,8 @@ module dec input logic exu_i0_br_valid_e4, // valid input logic exu_i0_br_mp_e4, // mispredict input logic exu_i0_br_middle_e4, // middle of bank - input logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // FGHR when predicted - + input logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // FGHR when predicted + // branch info from pipe1 for errors or counter updates input logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] exu_i1_br_index_e4, // index input logic [1:0] exu_i1_br_hist_e4, // history @@ -232,22 +232,22 @@ module dec `ifdef RV_BTB_48 input logic [1:0] exu_i1_br_way_e4, // way hit or repl input logic [1:0] exu_i0_br_way_e4, // way hit or repl -`else +`else input logic exu_i1_br_way_e4, // way hit or repl input logic exu_i0_br_way_e4, // way hit or repl -`endif - +`endif + output logic [31:0] gpr_i0_rs1_d, // gpr rs1 data output logic [31:0] gpr_i0_rs2_d, // gpr rs2 data - output logic [31:0] gpr_i1_rs1_d, - output logic [31:0] gpr_i1_rs2_d, - + output logic [31:0] gpr_i1_rs1_d, + output logic [31:0] gpr_i1_rs2_d, + output logic [31:0] dec_i0_immed_d, // immediate data - output logic [31:0] dec_i1_immed_d, - + output logic [31:0] dec_i1_immed_d, + output logic [12:1] dec_i0_br_immed_d, // br immediate data - output logic [12:1] dec_i1_br_immed_d, - + output logic [12:1] dec_i1_br_immed_d, + output alu_pkt_t i0_ap, // alu packet output alu_pkt_t i1_ap, @@ -255,14 +255,14 @@ module dec output logic dec_i1_alu_decode_d, output logic dec_i0_select_pc_d, // select pc onto rs1 for jal's - output logic dec_i1_select_pc_d, + output logic dec_i1_select_pc_d, output logic [31:1] dec_i0_pc_d, dec_i1_pc_d, // pc's at decode output logic dec_i0_rs1_bypass_en_d, // rs1 bypass enable output logic dec_i0_rs2_bypass_en_d, // rs2 bypass enable output logic dec_i1_rs1_bypass_en_d, output logic dec_i1_rs2_bypass_en_d, - + output logic [31:0] i0_rs1_bypass_data_d, // rs1 bypass data output logic [31:0] i0_rs2_bypass_data_d, // rs2 bypass data output logic [31:0] i1_rs1_bypass_data_d, @@ -273,20 +273,20 @@ module dec output lsu_pkt_t lsu_p, // lsu packet output mul_pkt_t mul_p, // mul packet output div_pkt_t div_p, // div packet - + output logic [11:0] dec_lsu_offset_d, // 12b offset for load/store addresses output logic dec_i0_lsu_d, // is load/store output logic dec_i1_lsu_d, - + output logic flush_final_e3, // final flush output logic i0_flush_final_e3, // final flush from i0 - output logic dec_csr_ren_d, // csr read enable + output logic dec_csr_ren_d, // csr read enable output logic dec_tlu_flush_lower_wb, // tlu flush due to late mp, exception, rfpc, or int output logic [31:1] dec_tlu_flush_path_wb, // tlu flush target - output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state - output logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state + output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state + output logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state output logic dec_tlu_fence_i_wb, // flush is a fence_i rfnpc, flush icache output logic dec_i0_mul_d, // chose which gpr value to use @@ -296,14 +296,14 @@ module dec output logic dec_i1_valid_e1, // i1 valid at e1 stage output logic dec_div_decode_e4, // div at e4 stage output logic [31:1] pred_correct_npc_e2, // npc if prediction is correct at e2 stage - + output logic dec_i0_rs1_bypass_en_e3, // rs1 bypass enable e3 output logic dec_i0_rs2_bypass_en_e3, // rs2 bypass enable e3 - output logic dec_i1_rs1_bypass_en_e3, - output logic dec_i1_rs2_bypass_en_e3, - output logic [31:0] i0_rs1_bypass_data_e3, // rs1 bypass data e3 + output logic dec_i1_rs1_bypass_en_e3, + output logic dec_i1_rs2_bypass_en_e3, + output logic [31:0] i0_rs1_bypass_data_e3, // rs1 bypass data e3 output logic [31:0] i0_rs2_bypass_data_e3, // rs2 bypass data e3 - output logic [31:0] i1_rs1_bypass_data_e3, + output logic [31:0] i1_rs1_bypass_data_e3, output logic [31:0] i1_rs2_bypass_data_e3, output logic dec_i0_sec_decode_e3, // secondary decode e3 output logic dec_i1_sec_decode_e3, @@ -328,11 +328,11 @@ module dec output logic dec_tlu_perfcnt3, // toggles when slot0 perf counter 3 has an event inc output predict_pkt_t i0_predict_p_d, // prediction packet to alus - output predict_pkt_t i1_predict_p_d, + output predict_pkt_t i1_predict_p_d, - output logic dec_i0_lsu_decode_d, // load/store decode - - output logic [31:0] i0_result_e4_eff, // alu result e4 + output logic dec_i0_lsu_decode_d, // load/store decode + + output logic [31:0] i0_result_e4_eff, // alu result e4 output logic [31:0] i1_result_e4_eff, output logic dec_tlu_i0_valid_e4, // slot 0 instruction is valid at e4 @@ -342,12 +342,12 @@ module dec output logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control output logic [31:1] dec_tlu_i0_pc_e4, // pc e4 - output logic [31:1] dec_tlu_i1_pc_e4, + output logic [31:1] dec_tlu_i1_pc_e4, output logic [4:2] dec_i0_data_en, // clock-gate control logic - output logic [4:1] dec_i0_ctl_en, + output logic [4:1] dec_i0_ctl_en, output logic [4:2] dec_i1_data_en, - output logic [4:1] dec_i1_ctl_en, + output logic [4:1] dec_i1_ctl_en, output logic dec_nonblock_load_freeze_dc2, // lsu must freeze nonblock load due to younger dependency in pipe @@ -355,7 +355,7 @@ module dec input logic [15:0] ifu_i1_cinst, output trace_pkt_t trace_rv_trace_pkt, // trace packet for trace - + // feature disable from mfdc output logic dec_tlu_core_ecc_disable, // disable core ECC output logic dec_tlu_sec_alu_disable, // disable secondary ALU @@ -375,8 +375,8 @@ module dec output logic dec_tlu_dccm_clk_override, // override DCCM clock domain gating output logic dec_tlu_icm_clk_override, // override ICCM clock domain gating - input logic scan_mode - + input logic scan_mode + ); localparam GPR_BANKS = 1; @@ -384,7 +384,7 @@ module dec logic dec_tlu_dec_clk_override; // to and from dec blocks logic clk_override; - + logic dec_ib1_valid_d; logic dec_ib0_valid_d; @@ -392,55 +392,55 @@ module dec logic dec_pmu_decode_stall; logic dec_pmu_presync_stall; logic dec_pmu_postsync_stall; - + logic dec_tlu_wr_pause_wb; // CSR write to pause reg is at WB. - + logic dec_i0_rs1_en_d; logic dec_i0_rs2_en_d; logic dec_fence_pending; // tell TLU to stall DMA logic [4:0] dec_i0_rs1_d; logic [4:0] dec_i0_rs2_d; - + logic dec_i1_rs1_en_d; logic dec_i1_rs2_en_d; logic [4:0] dec_i1_rs1_d; logic [4:0] dec_i1_rs2_d; - + logic [31:0] dec_i0_instr_d, dec_i1_instr_d; logic dec_tlu_pipelining_disable; logic dec_tlu_dual_issue_disable; - - + + logic [4:0] dec_i0_waddr_wb; logic dec_i0_wen_wb; logic [31:0] dec_i0_wdata_wb; - + logic [4:0] dec_i1_waddr_wb; logic dec_i1_wen_wb; logic [31:0] dec_i1_wdata_wb; - - logic dec_csr_wen_wb; // csr write enable at wb - logic [11:0] dec_csr_rdaddr_d; // read address for csr + + logic dec_csr_wen_wb; // csr write enable at wb + logic [11:0] dec_csr_rdaddr_d; // read address for csr logic [11:0] dec_csr_wraddr_wb; // write address for csryes - + logic [31:0] dec_csr_wrdata_wb; // csr write data at wb logic [31:0] dec_csr_rddata_d; // csr read data at wb - logic dec_csr_legal_d; // csr indicates legal operation + logic dec_csr_legal_d; // csr indicates legal operation logic dec_csr_wen_unq_d; // valid csr with write - for csr legal - logic dec_csr_any_unq_d; // valid csr - for csr legal + logic dec_csr_any_unq_d; // valid csr - for csr legal logic dec_csr_stall_int_ff; // csr is mie/mstatus - + trap_pkt_t dec_tlu_packet_e4; - + logic dec_i0_pc4_d, dec_i1_pc4_d; logic dec_tlu_presync_d; logic dec_tlu_postsync_d; @@ -448,7 +448,7 @@ module dec logic [31:0] dec_illegal_inst; - + // GPR Bank ID write signals logic wen_bank_id; logic [GPR_BANKS_LOG2-1:0] wr_bank_id; @@ -466,26 +466,26 @@ module dec logic dec_i0_decode_d; logic dec_i1_decode_d; - + logic [3:0] dec_i0_trigger_match_d; logic [3:0] dec_i1_trigger_match_d; - + logic dec_debug_fence_d; logic dec_nonblock_load_wen; logic [4:0] dec_nonblock_load_waddr; logic dec_tlu_flush_pause_wb; - + br_pkt_t dec_i0_brp; br_pkt_t dec_i1_brp; - + assign clk_override = dec_tlu_dec_clk_override; assign dec_dbg_rddata[31:0] = dec_i0_wdata_wb[31:0]; - + dec_ib_ctl instbuff (.* ); @@ -498,7 +498,7 @@ module dec assign wr_bank_id = '0; - + dec_gpr_ctl #(.GPR_BANKS(GPR_BANKS), .GPR_BANKS_LOG2(GPR_BANKS_LOG2)) arf (.*, // inputs @@ -506,24 +506,24 @@ module dec .raddr1(dec_i0_rs2_d[4:0]), .rden1(dec_i0_rs2_en_d), .raddr2(dec_i1_rs1_d[4:0]), .rden2(dec_i1_rs1_en_d), .raddr3(dec_i1_rs2_d[4:0]), .rden3(dec_i1_rs2_en_d), - + .waddr0(dec_i0_waddr_wb[4:0]), .wen0(dec_i0_wen_wb), .wd0(dec_i0_wdata_wb[31:0]), - .waddr1(dec_i1_waddr_wb[4:0]), .wen1(dec_i1_wen_wb), .wd1(dec_i1_wdata_wb[31:0]), - .waddr2(dec_nonblock_load_waddr[4:0]), .wen2(dec_nonblock_load_wen), .wd2(lsu_nonblock_load_data[31:0]), - + .waddr1(dec_i1_waddr_wb[4:0]), .wen1(dec_i1_wen_wb), .wd1(dec_i1_wdata_wb[31:0]), + .waddr2(dec_nonblock_load_waddr[4:0]), .wen2(dec_nonblock_load_wen), .wd2(lsu_nonblock_load_data[31:0]), + // outputs .rd0(gpr_i0_rs1_d[31:0]), .rd1(gpr_i0_rs2_d[31:0]), - .rd2(gpr_i1_rs1_d[31:0]), .rd3(gpr_i1_rs2_d[31:0]) + .rd2(gpr_i1_rs1_d[31:0]), .rd3(gpr_i1_rs2_d[31:0]) ); - + // Trigger - + dec_trigger dec_trigger (.*); - + // trace logic [15:0] dec_i0_cinst_d; logic [15:0] dec_i1_cinst_d; @@ -538,7 +538,7 @@ module dec logic dec_tlu_i0_exc_valid_wb1, dec_tlu_i1_exc_valid_wb1; // also need retires_p==3 - + assign trace_rv_trace_pkt.trace_rv_i_insn_ip = { 32'b0, dec_i1_inst_wb1[31:0], dec_i0_inst_wb1[31:0] }; assign trace_rv_trace_pkt.trace_rv_i_address_ip = { 32'b0, dec_i1_pc_wb1[31:1], 1'b0, dec_i0_pc_wb1[31:1], 1'b0 }; @@ -551,9 +551,9 @@ module dec assign trace_rv_trace_pkt.trace_rv_i_interrupt_ip = {dec_tlu_int_valid_wb1,2'b0}; assign trace_rv_trace_pkt.trace_rv_i_tval_ip = dec_tlu_mtval_wb1[31:0]; // replicate across ports - - + + // end trace - + endmodule // dec diff --git a/design/dec/dec_decode_ctl.sv b/design/dec/dec_decode_ctl.sv index 02a8ef2..25a51d7 100644 --- a/design/dec/dec_decode_ctl.sv +++ b/design/dec/dec_decode_ctl.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,19 +21,19 @@ module dec_decode_ctl input logic [15:0] dec_i1_cinst_d, output logic [31:0] dec_i0_inst_wb1, // 32b instruction at wb+1 for trace encoder - output logic [31:0] dec_i1_inst_wb1, + output logic [31:0] dec_i1_inst_wb1, output logic [31:1] dec_i0_pc_wb1, // 31b pc at wb+1 for trace encoder - output logic [31:1] dec_i1_pc_wb1, + output logic [31:1] dec_i1_pc_wb1, - - input logic lsu_nonblock_load_valid_dc3, // valid nonblock load at dc3 - input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // -> corresponding tag - input logic lsu_nonblock_load_inv_dc5, // invalidate request for nonblock load dc5 - input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // -> corresponding tag - input logic lsu_nonblock_load_data_valid, // valid nonblock load data back - input logic lsu_nonblock_load_data_error, // nonblock load bus error - input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag + + input logic lsu_nonblock_load_valid_dc3, // valid nonblock load at dc3 + input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // -> corresponding tag + input logic lsu_nonblock_load_inv_dc5, // invalidate request for nonblock load dc5 + input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // -> corresponding tag + input logic lsu_nonblock_load_data_valid, // valid nonblock load data back + input logic lsu_nonblock_load_data_error, // nonblock load bus error + input logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // -> corresponding tag input logic [3:0] dec_i0_trigger_match_d, // i0 decode trigger matches input logic [3:0] dec_i1_trigger_match_d, // i1 decode trigger matches @@ -41,26 +41,26 @@ module dec_decode_ctl input logic dec_tlu_wr_pause_wb, // pause instruction at wb input logic dec_tlu_pipelining_disable, // pipeline disable - presync, i0 decode only input logic dec_tlu_dual_issue_disable, // i0 decode only - + input logic dec_tlu_sec_alu_disable, // no alu ops sent to secondary alus - + input logic [3:0] lsu_trigger_match_dc3, // lsu trigger matches input logic lsu_pmu_misaligned_dc3, // perf mon: load/store misalign input logic dec_tlu_debug_stall, // debug stall decode input logic dec_tlu_flush_leak_one_wb, // leak1 instruction - + input logic dec_debug_fence_d, // debug fence instruction - + input logic [1:0] dbg_cmd_wrdata, // disambiguate fence, fence_i - input logic dec_i0_icaf_d, // icache access fault - input logic dec_i1_icaf_d, + input logic dec_i0_icaf_d, // icache access fault + input logic dec_i1_icaf_d, input logic dec_i0_icaf_f1_d, // i0 instruction access fault at decode for f1 fetch group - input logic dec_i0_perr_d, // icache parity error - input logic dec_i1_perr_d, + input logic dec_i0_perr_d, // icache parity error + input logic dec_i1_perr_d, input logic dec_i0_sbecc_d, // icache/iccm single-bit error - input logic dec_i1_sbecc_d, + input logic dec_i1_sbecc_d, input logic dec_i0_dbecc_d, // icache/iccm double-bit error input logic dec_i1_dbecc_d, @@ -70,10 +70,10 @@ module dec_decode_ctl input logic [15:0] ifu_illegal_inst, // 16b illegal inst from aligner input logic [31:1] dec_i0_pc_d, // pc - + input logic lsu_freeze_dc3, // freeze pipe: decode -> dc3 input logic lsu_idle_any, // lsu idle: if fence instr & ~lsu_idle then stall decode - + input logic lsu_store_stall_any, // stall any store at decode input logic dma_dccm_stall_any, // stall any load/store at decode @@ -81,105 +81,105 @@ module dec_decode_ctl input logic exu_div_stall, // div executing: stall decode input logic [31:0] exu_div_result, // div result - input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state - input logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state + input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state + input logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state input logic dec_tlu_flush_lower_wb, // trap lower flush input logic dec_tlu_flush_pause_wb, // don't clear pause state on initial lower flush input logic dec_tlu_presync_d, // CSR read needs to be presync'd - input logic dec_tlu_postsync_d, // CSR ops that need to be postsync'd - + input logic dec_tlu_postsync_d, // CSR ops that need to be postsync'd + input logic [31:0] exu_mul_result_e3, // multiply result input logic dec_i0_pc4_d, // inst is 4B inst else 2B input logic dec_i1_pc4_d, - + input logic [31:0] dec_csr_rddata_d, // csr read data at wb input logic dec_csr_legal_d, // csr indicates legal operation input logic [31:0] exu_csr_rs1_e1, // rs1 for csr instr - + input logic [31:0] lsu_result_dc3, // load result input logic exu_i0_flush_final, // lower flush or i0 flush at e2 input logic exu_i1_flush_final, // lower flush or i1 flush at e2 - input logic [31:1] exu_i0_pc_e1, // pcs at e1 - input logic [31:1] exu_i1_pc_e1, - + input logic [31:1] exu_i0_pc_e1, // pcs at e1 + input logic [31:1] exu_i1_pc_e1, + input logic [31:0] dec_i0_instr_d, // inst at decode input logic [31:0] dec_i1_instr_d, input logic dec_ib0_valid_d, // inst valid at decode input logic dec_ib1_valid_d, - + input logic [31:0] exu_i0_result_e1, // from primary alu's - input logic [31:0] exu_i1_result_e1, - + input logic [31:0] exu_i1_result_e1, + input logic [31:0] exu_i0_result_e4, // from secondary alu's - input logic [31:0] exu_i1_result_e4, - + input logic [31:0] exu_i1_result_e4, + input logic clk, // for rvdffe's input logic active_clk, // clk except for halt / pause input logic free_clk, // free running clock - + input logic clk_override, // test stuff input logic rst_l, output logic dec_i0_rs1_en_d, // rs1 enable at decode - output logic dec_i0_rs2_en_d, + output logic dec_i0_rs2_en_d, output logic [4:0] dec_i0_rs1_d, // rs1 logical source output logic [4:0] dec_i0_rs2_d, - - + + output logic [31:0] dec_i0_immed_d, // 32b immediate data decode - + output logic dec_i1_rs1_en_d, output logic dec_i1_rs2_en_d, output logic [4:0] dec_i1_rs1_d, output logic [4:0] dec_i1_rs2_d, - - + + output logic [31:0] dec_i1_immed_d, output logic [12:1] dec_i0_br_immed_d, // 12b branch immediate - output logic [12:1] dec_i1_br_immed_d, - + output logic [12:1] dec_i1_br_immed_d, + output alu_pkt_t i0_ap, // alu packets output alu_pkt_t i1_ap, output logic dec_i0_decode_d, // i0 decode output logic dec_i1_decode_d, - output logic dec_ib0_valid_eff_d, // effective valid taking decode into account + output logic dec_ib0_valid_eff_d, // effective valid taking decode into account output logic dec_ib1_valid_eff_d, - + output logic dec_i0_alu_decode_d, // decode to primary alu's output logic dec_i1_alu_decode_d, - + output logic [31:0] i0_rs1_bypass_data_d, // i0 rs1 bypass data output logic [31:0] i0_rs2_bypass_data_d, // i0 rs2 bypass data output logic [31:0] i1_rs1_bypass_data_d, output logic [31:0] i1_rs2_bypass_data_d, - - + + output logic [4:0] dec_i0_waddr_wb, // i0 logical source to write to gpr's output logic dec_i0_wen_wb, // i0 write enable output logic [31:0] dec_i0_wdata_wb, // i0 write data - + output logic [4:0] dec_i1_waddr_wb, output logic dec_i1_wen_wb, output logic [31:0] dec_i1_wdata_wb, - + output logic dec_i0_select_pc_d, // i0 select pc for rs1 - branches - output logic dec_i1_select_pc_d, - + output logic dec_i1_select_pc_d, + output logic dec_i0_rs1_bypass_en_d, // i0 rs1 bypass enable output logic dec_i0_rs2_bypass_en_d, // i0 rs2 bypass enable output logic dec_i1_rs1_bypass_en_d, @@ -190,7 +190,7 @@ module dec_decode_ctl output mul_pkt_t mul_p, // multiply packet output div_pkt_t div_p, // divide packet - + output logic [11:0] dec_lsu_offset_d, output logic dec_i0_lsu_d, // chose which gpr value to use output logic dec_i1_lsu_d, @@ -202,21 +202,21 @@ module dec_decode_ctl // review output logic flush_final_e3, // flush final at e3: i0 or i1 output logic i0_flush_final_e3, // i0 flush final at e3 - + output logic dec_csr_ren_d, // valid csr decode output logic dec_csr_wen_unq_d, // valid csr with write - for csr legal - output logic dec_csr_any_unq_d, // valid csr - for csr legal - output logic dec_csr_wen_wb, // csr write enable at wb + output logic dec_csr_any_unq_d, // valid csr - for csr legal + output logic dec_csr_wen_wb, // csr write enable at wb output logic [11:0] dec_csr_rdaddr_d, // read address for csr output logic [11:0] dec_csr_wraddr_wb, // write address for csr - output logic [31:0] dec_csr_wrdata_wb, // csr write data at wb + output logic [31:0] dec_csr_wrdata_wb, // csr write data at wb output logic dec_csr_stall_int_ff, // csr is mie/mstatus - + output dec_tlu_i0_valid_e4, // i0 valid inst at e4 output dec_tlu_i1_valid_e4, - + output trap_pkt_t dec_tlu_packet_e4, // trap packet - + output logic dec_fence_pending, // tell TLU to stall DMA output logic [31:1] dec_tlu_i0_pc_e4, // i0 trap pc output logic [31:1] dec_tlu_i1_pc_e4, @@ -224,11 +224,11 @@ module dec_decode_ctl output logic [31:0] dec_illegal_inst, // illegal inst output logic dec_i1_valid_e1, // i1 valid e1 output logic dec_div_decode_e4, // i0 div e4 - output logic [31:1] pred_correct_npc_e2, // npc e2 if the prediction is correct + output logic [31:1] pred_correct_npc_e2, // npc e2 if the prediction is correct output logic dec_i0_rs1_bypass_en_e3, // i0 rs1 bypass enables e3 output logic dec_i0_rs2_bypass_en_e3, // i1 rs1 bypass enables e3 output logic dec_i1_rs1_bypass_en_e3, - output logic dec_i1_rs2_bypass_en_e3, + output logic dec_i1_rs2_bypass_en_e3, output logic [31:0] i0_rs1_bypass_data_e3, // i0 rs1 bypass data e3 output logic [31:0] i0_rs2_bypass_data_e3, // i1 rs1 bypass data e3 output logic [31:0] i1_rs1_bypass_data_e3, @@ -249,17 +249,17 @@ module dec_decode_ctl output predict_pkt_t i0_predict_p_d, // i0 predict packet decode output predict_pkt_t i1_predict_p_d, - + output logic dec_i0_lsu_decode_d, // i0 lsu decode - + output logic [31:0] i0_result_e4_eff, // i0 e4 result taking freeze into account output logic [31:0] i1_result_e4_eff, output logic [31:0] i0_result_e2, // i0 result e2 output logic [4:2] dec_i0_data_en, // clock-gating logic - output logic [4:1] dec_i0_ctl_en, + output logic [4:1] dec_i0_ctl_en, output logic [4:2] dec_i1_data_en, - output logic [4:1] dec_i1_ctl_en, + output logic [4:1] dec_i1_ctl_en, output logic [1:0] dec_pmu_instr_decoded, // number of instructions decode this cycle encoded output logic dec_pmu_decode_stall, // decode is stalled @@ -270,16 +270,16 @@ module dec_decode_ctl output logic [4:0] dec_nonblock_load_waddr, // logical write addr for nonblock load output logic dec_nonblock_load_freeze_dc2, // lsu must freeze nonblock load due to younger dependency in pipe output logic dec_pause_state, // core in pause state - + input logic scan_mode ); - + dec_pkt_t i0_dp_raw, i0_dp; dec_pkt_t i1_dp_raw, i1_dp; - + logic [31:0] i0, i1; @@ -289,7 +289,7 @@ module dec_decode_ctl logic [31:0] i1_result_e2; logic [31:0] i0_result_e3, i1_result_e3; logic [31:0] i0_result_e4, i1_result_e4; - logic [31:0] i0_result_wb, i1_result_wb; + logic [31:0] i0_result_wb, i1_result_wb; logic [31:1] i0_pc_e1, i1_pc_e1; logic [31:1] i0_pc_e2, i1_pc_e2; @@ -297,7 +297,7 @@ module dec_decode_ctl logic [31:1] i0_pc_e4, i1_pc_e4; logic [9:0] i0_rs1bypass, i0_rs2bypass; - logic [9:0] i1_rs1bypass, i1_rs2bypass; + logic [9:0] i1_rs1bypass, i1_rs2bypass; logic i0_jalimm20, i1_jalimm20; logic i0_uiimm20, i1_uiimm20; @@ -306,16 +306,16 @@ module dec_decode_ctl logic lsu_decode_d; logic [31:0] i0_immed_d; - logic i0_presync; - logic i0_postsync; + logic i0_presync; + logic i0_postsync; logic postsync_stall; logic ps_stall; - + logic prior_inflight, prior_inflight_e1e4, prior_inflight_wb; - + logic csr_clr_d, csr_set_d, csr_write_d; - + logic csr_clr_e1,csr_set_e1,csr_write_e1,csr_imm_e1; logic [31:0] csr_mask_e1; @@ -335,11 +335,11 @@ module dec_decode_ctl logic i1_load2_block_d; logic i1_mul2_block_d; logic mul_decode_d; - logic div_decode_d; + logic div_decode_d; logic [31:1] div_pc; logic div_stall, div_stall_ff; logic [3:0] div_trigger; - + logic i0_legal; logic shift_illegal; logic illegal_inst_en; @@ -354,13 +354,13 @@ module dec_decode_ctl logic [12:1] last_br_immed_d; logic i1_depend_i0_d; logic i0_rs1_depend_i0_e1, i0_rs1_depend_i0_e2, i0_rs1_depend_i0_e3, i0_rs1_depend_i0_e4, i0_rs1_depend_i0_wb; - logic i0_rs1_depend_i1_e1, i0_rs1_depend_i1_e2, i0_rs1_depend_i1_e3, i0_rs1_depend_i1_e4, i0_rs1_depend_i1_wb; + logic i0_rs1_depend_i1_e1, i0_rs1_depend_i1_e2, i0_rs1_depend_i1_e3, i0_rs1_depend_i1_e4, i0_rs1_depend_i1_wb; logic i0_rs2_depend_i0_e1, i0_rs2_depend_i0_e2, i0_rs2_depend_i0_e3, i0_rs2_depend_i0_e4, i0_rs2_depend_i0_wb; - logic i0_rs2_depend_i1_e1, i0_rs2_depend_i1_e2, i0_rs2_depend_i1_e3, i0_rs2_depend_i1_e4, i0_rs2_depend_i1_wb; + logic i0_rs2_depend_i1_e1, i0_rs2_depend_i1_e2, i0_rs2_depend_i1_e3, i0_rs2_depend_i1_e4, i0_rs2_depend_i1_wb; logic i1_rs1_depend_i0_e1, i1_rs1_depend_i0_e2, i1_rs1_depend_i0_e3, i1_rs1_depend_i0_e4, i1_rs1_depend_i0_wb; - logic i1_rs1_depend_i1_e1, i1_rs1_depend_i1_e2, i1_rs1_depend_i1_e3, i1_rs1_depend_i1_e4, i1_rs1_depend_i1_wb; + logic i1_rs1_depend_i1_e1, i1_rs1_depend_i1_e2, i1_rs1_depend_i1_e3, i1_rs1_depend_i1_e4, i1_rs1_depend_i1_wb; logic i1_rs2_depend_i0_e1, i1_rs2_depend_i0_e2, i1_rs2_depend_i0_e3, i1_rs2_depend_i0_e4, i1_rs2_depend_i0_wb; - logic i1_rs2_depend_i1_e1, i1_rs2_depend_i1_e2, i1_rs2_depend_i1_e3, i1_rs2_depend_i1_e4, i1_rs2_depend_i1_wb; + logic i1_rs2_depend_i1_e1, i1_rs2_depend_i1_e2, i1_rs2_depend_i1_e3, i1_rs2_depend_i1_e4, i1_rs2_depend_i1_wb; logic i1_rs1_depend_i0_d, i1_rs2_depend_i0_d; logic i0_secondary_d, i1_secondary_d; @@ -371,24 +371,24 @@ module dec_decode_ctl logic i0_load_block_d; logic i0_mul_block_d; logic [3:0] i0_rs1_depth_d, i0_rs2_depth_d; - logic [3:0] i1_rs1_depth_d, i1_rs2_depth_d; + logic [3:0] i1_rs1_depth_d, i1_rs2_depth_d; logic i0_rs1_match_e1_e2, i0_rs1_match_e1_e3; - logic i0_rs2_match_e1_e2, i0_rs2_match_e1_e3; + logic i0_rs2_match_e1_e2, i0_rs2_match_e1_e3; logic i1_rs1_match_e1_e2, i1_rs1_match_e1_e3; - logic i1_rs2_match_e1_e2, i1_rs2_match_e1_e3; + logic i1_rs2_match_e1_e2, i1_rs2_match_e1_e3; logic i0_load_stall_d, i1_load_stall_d; - logic i0_store_stall_d, i1_store_stall_d; + logic i0_store_stall_d, i1_store_stall_d; logic i0_predict_nt, i0_predict_t; - logic i1_predict_nt, i1_predict_t; - + logic i1_predict_nt, i1_predict_t; + logic i0_notbr_error, i0_br_toffset_error; logic i1_notbr_error, i1_br_toffset_error; logic i0_ret_error, i1_ret_error; - logic i0_br_error, i1_br_error; - logic i0_br_error_all, i1_br_error_all; + logic i0_br_error, i1_br_error; + logic i0_br_error_all, i1_br_error_all; logic [11:0] i0_br_offset, i1_br_offset; logic freeze; @@ -396,49 +396,49 @@ module dec_decode_ctl logic [20:1] i0_pcall_imm, i1_pcall_imm; // predicted jal's logic i0_pcall_12b_offset, i1_pcall_12b_offset; logic i0_pcall_raw, i1_pcall_raw; - logic i0_pcall_case, i1_pcall_case; + logic i0_pcall_case, i1_pcall_case; logic i0_pcall, i1_pcall; logic i0_pja_raw, i1_pja_raw; - logic i0_pja_case, i1_pja_case; + logic i0_pja_case, i1_pja_case; logic i0_pja, i1_pja; logic i0_pret_case, i1_pret_case; logic i0_pret_raw, i0_pret; - logic i1_pret_raw, i1_pret; - - logic i0_jal, i1_jal; // jal's that are not predicted - + logic i1_pret_raw, i1_pret; + + logic i0_jal, i1_jal; // jal's that are not predicted + logic i0_predict_br, i1_predict_br; logic freeze_prior1, freeze_prior2; logic [31:0] i0_result_e4_freeze, i1_result_e4_freeze; - logic [31:0] i0_result_wb_freeze, i1_result_wb_freeze; + logic [31:0] i0_result_wb_freeze, i1_result_wb_freeze; logic [31:0] i1_result_wb_eff, i0_result_wb_eff; logic [2:0] i1rs1_intra, i1rs2_intra; logic i1_rs1_intra_bypass, i1_rs2_intra_bypass; logic store_data_bypass_c1, store_data_bypass_c2; logic [1:0] store_data_bypass_e4_c1, store_data_bypass_e4_c2, store_data_bypass_e4_c3; logic store_data_bypass_i0_e2_c2; - + class_pkt_t i0_rs1_class_d, i0_rs2_class_d; - class_pkt_t i1_rs1_class_d, i1_rs2_class_d; + class_pkt_t i1_rs1_class_d, i1_rs2_class_d; class_pkt_t i0_dc, i0_e1c, i0_e2c, i0_e3c, i0_e4c, i0_wbc; class_pkt_t i1_dc, i1_e1c, i1_e2c, i1_e3c, i1_e4c, i1_wbc; logic i0_rs1_match_e1, i0_rs1_match_e2, i0_rs1_match_e3; - logic i1_rs1_match_e1, i1_rs1_match_e2, i1_rs1_match_e3; + logic i1_rs1_match_e1, i1_rs1_match_e2, i1_rs1_match_e3; logic i0_rs2_match_e1, i0_rs2_match_e2, i0_rs2_match_e3; - logic i1_rs2_match_e1, i1_rs2_match_e2, i1_rs2_match_e3; - + logic i1_rs2_match_e1, i1_rs2_match_e2, i1_rs2_match_e3; + logic i0_secondary_stall_d; logic i0_ap_pc2, i0_ap_pc4; - logic i1_ap_pc2, i1_ap_pc4; + logic i1_ap_pc2, i1_ap_pc4; logic div_wen_wb; logic i0_rd_en_d; @@ -448,10 +448,10 @@ module dec_decode_ctl logic load_ldst_bypass_c1; logic load_mul_rs1_bypass_e1; - logic load_mul_rs2_bypass_e1; - + logic load_mul_rs2_bypass_e1; + logic leak1_i0_stall_in, leak1_i0_stall; - logic leak1_i1_stall_in, leak1_i1_stall; + logic leak1_i1_stall_in, leak1_i1_stall; logic leak1_mode; logic i0_csr_write_only_d; @@ -463,11 +463,11 @@ module dec_decode_ctl logic [5:0] i0_pipe_en; logic i0_e1_ctl_en, i0_e2_ctl_en, i0_e3_ctl_en, i0_e4_ctl_en, i0_wb_ctl_en; - logic i0_e1_data_en, i0_e2_data_en, i0_e3_data_en, i0_e4_data_en, i0_wb_data_en, i0_wb1_data_en; - + logic i0_e1_data_en, i0_e2_data_en, i0_e3_data_en, i0_e4_data_en, i0_wb_data_en, i0_wb1_data_en; + logic [5:0] i1_pipe_en; logic i1_e1_ctl_en, i1_e2_ctl_en, i1_e3_ctl_en, i1_e4_ctl_en, i1_wb_ctl_en; - logic i1_e1_data_en, i1_e2_data_en, i1_e3_data_en, i1_e4_data_en, i1_wb_data_en, i1_wb1_data_en; + logic i1_e1_data_en, i1_e2_data_en, i1_e3_data_en, i1_e4_data_en, i1_wb_data_en, i1_wb1_data_en; logic debug_fence_i; logic debug_fence; @@ -480,13 +480,13 @@ module dec_decode_ctl logic i1_icaf_d; logic i0_not_alu_eff, i1_not_alu_eff; - + logic disable_secondary; logic clear_pause; logic pause_state_in, pause_state; logic pause_stall; - + logic [31:1] i1_pc_wb; logic i0_brp_valid; @@ -496,36 +496,36 @@ module dec_decode_ctl logic i0_block_d; logic i1_block_d; logic ps_stall_in; - + logic freeze_after_unfreeze1; logic freeze_after_unfreeze2; logic unfreeze_cycle1; logic unfreeze_cycle2; - + assign freeze = lsu_freeze_dc3; `ifdef RV_NO_SECONDARY_ALU assign disable_secondary = 1; -`else +`else assign disable_secondary = dec_tlu_sec_alu_disable; `endif - - + + // branch prediction // in leak1_mode, ignore any predictions for i0, treat branch as if we haven't seen it before // in leak1 mode, also ignore branch errors for i0 assign i0_brp_valid = dec_i0_brp.valid & ~leak1_mode; - + assign i0_predict_p_d.misp = '0; assign i0_predict_p_d.ataken = '0; assign i0_predict_p_d.boffset = '0; assign i0_predict_p_d.pcall = i0_pcall; // dont mark as pcall if branch error - assign i0_predict_p_d.pja = i0_pja; - assign i0_predict_p_d.pret = i0_pret; + assign i0_predict_p_d.pja = i0_pja; + assign i0_predict_p_d.pret = i0_pret; assign i0_predict_p_d.prett[31:1] = dec_i0_brp.prett[31:1]; assign i0_predict_p_d.pc4 = dec_i0_pc4_d; assign i0_predict_p_d.hist[1:0] = dec_i0_brp.hist[1:0]; @@ -545,22 +545,22 @@ module dec_decode_ctl assign i0_predict_p_d.toffset[11:0] = i0_br_offset[11:0]; assign i0_predict_p_d.fghr[`RV_BHT_GHR_RANGE] = dec_i0_brp.fghr[`RV_BHT_GHR_RANGE]; assign i0_predict_p_d.way = dec_i0_brp.way; - + assign i1_predict_p_d.misp = '0; assign i1_predict_p_d.ataken = '0; assign i1_predict_p_d.boffset = '0; assign i1_predict_p_d.pcall = i1_pcall; - assign i1_predict_p_d.pja = i1_pja; - assign i1_predict_p_d.pret = i1_pret; + assign i1_predict_p_d.pja = i1_pja; + assign i1_predict_p_d.pret = i1_pret; assign i1_predict_p_d.prett[31:1] = dec_i1_brp.prett[31:1]; assign i1_predict_p_d.pc4 = dec_i1_pc4_d; assign i1_predict_p_d.hist[1:0] = dec_i1_brp.hist[1:0]; assign i1_predict_p_d.valid = dec_i1_brp.valid & dec_i1_decode_d; assign i1_notbr_error = dec_i1_brp.valid & ~(i1_dp_raw.condbr | i1_pcall_raw | i1_pja_raw | i1_pret_raw); - + assign i1_br_toffset_error = dec_i1_brp.valid & dec_i1_brp.hist[1] & (dec_i1_brp.toffset[11:0] != i1_br_offset[11:0]) & !i1_pret_raw; assign i1_ret_error = dec_i1_brp.valid & dec_i1_brp.ret & ~i1_pret_raw; assign i1_br_error = dec_i1_brp.br_error | i1_notbr_error | i1_br_toffset_error | i1_ret_error; @@ -570,7 +570,7 @@ module dec_decode_ctl assign i1_predict_p_d.bank[1:0] = dec_i1_brp.bank[1:0]; assign i1_predict_p_d.btag[`RV_BTB_BTAG_SIZE-1:0] = dec_i1_brp.btag[`RV_BTB_BTAG_SIZE-1:0]; assign i1_br_error_all = (i1_br_error | dec_i1_brp.br_start_error); - assign i1_predict_p_d.toffset[11:0] = i1_br_offset[11:0]; + assign i1_predict_p_d.toffset[11:0] = i1_br_offset[11:0]; assign i1_predict_p_d.fghr[`RV_BHT_GHR_RANGE] = dec_i1_brp.fghr[`RV_BHT_GHR_RANGE]; assign i1_predict_p_d.way = dec_i1_brp.way; @@ -582,7 +582,7 @@ module dec_decode_ctl assign i0_icaf_d = dec_i0_icaf_d | dec_i0_dbecc_d; assign i1_icaf_d = dec_i1_icaf_d | dec_i1_dbecc_d; - + assign i0_instr_error = i0_icaf_d | dec_i0_perr_d | dec_i0_sbecc_d; always_comb begin @@ -605,25 +605,25 @@ module dec_decode_ctl i1_dp.lor = 1'b1; i1_dp.legal = 1'b1; end - + end - + assign flush_lower_wb = dec_tlu_flush_lower_wb; - + assign i0[31:0] = dec_i0_instr_d[31:0]; - assign i1[31:0] = dec_i1_instr_d[31:0]; - + assign i1[31:0] = dec_i1_instr_d[31:0]; + assign dec_i0_select_pc_d = i0_dp.pc; - assign dec_i1_select_pc_d = i1_dp.pc; + assign dec_i1_select_pc_d = i1_dp.pc; // branches that can be predicted assign i0_predict_br = i0_dp.condbr | i0_pcall | i0_pja | i0_pret; - assign i1_predict_br = i1_dp.condbr | i1_pcall | i1_pja | i1_pret; - + assign i1_predict_br = i1_dp.condbr | i1_pcall | i1_pja | i1_pret; + assign i0_predict_nt = ~(dec_i0_brp.hist[1] & i0_brp_valid) & i0_predict_br; - assign i0_predict_t = (dec_i0_brp.hist[1] & i0_brp_valid) & i0_predict_br; + assign i0_predict_t = (dec_i0_brp.hist[1] & i0_brp_valid) & i0_predict_br; assign i0_ap.valid = (i0_dc.sec | i0_dc.alu | i0_dp.alu ); assign i0_ap.add = i0_dp.add; @@ -642,23 +642,23 @@ module dec_decode_ctl assign i0_ap.bge = i0_dp.bge; - + assign i0_ap.csr_write = i0_csr_write_only_d; assign i0_ap.csr_imm = i0_dp.csr_imm; - - + + assign i0_ap.jal = i0_jal; - + assign i0_ap_pc2 = ~dec_i0_pc4_d; assign i0_ap_pc4 = dec_i0_pc4_d; - + assign i0_ap.predict_nt = i0_predict_nt; assign i0_ap.predict_t = i0_predict_t; - + assign i1_predict_nt = ~(dec_i1_brp.hist[1] & dec_i1_brp.valid) & i1_predict_br; - assign i1_predict_t = (dec_i1_brp.hist[1] & dec_i1_brp.valid) & i1_predict_br; - + assign i1_predict_t = (dec_i1_brp.hist[1] & dec_i1_brp.valid) & i1_predict_br; + assign i1_ap.valid = (i1_dc.sec | i1_dc.alu | i1_dp.alu); assign i1_ap.add = i1_dp.add; assign i1_ap.sub = i1_dp.sub; @@ -677,30 +677,30 @@ module dec_decode_ctl assign i1_ap.csr_write = 1'b0; assign i1_ap.csr_imm = 1'b0; - + assign i1_ap.jal = i1_jal; - + assign i1_ap_pc2 = ~dec_i1_pc4_d; assign i1_ap_pc4 = dec_i1_pc4_d; - + assign i1_ap.predict_nt = i1_predict_nt; assign i1_ap.predict_t = i1_predict_t; localparam NBLOAD_SIZE = `RV_LSU_NUM_NBLOAD; localparam NBLOAD_SIZE_MSB = `RV_LSU_NUM_NBLOAD-1; - localparam NBLOAD_TAG_MSB = `RV_LSU_NUM_NBLOAD_WIDTH-1; - + localparam NBLOAD_TAG_MSB = `RV_LSU_NUM_NBLOAD_WIDTH-1; + // non block load cam logic - + logic cam_write, cam_inv_reset, cam_data_reset; logic [NBLOAD_TAG_MSB:0] cam_write_tag, cam_inv_reset_tag, cam_data_reset_tag; - logic [NBLOAD_SIZE_MSB:0] cam_wen; + logic [NBLOAD_SIZE_MSB:0] cam_wen; logic [NBLOAD_TAG_MSB:0] load_data_tag; logic [NBLOAD_SIZE_MSB:0] nonblock_load_write; - + load_cam_pkt_t [NBLOAD_SIZE_MSB:0] cam; - load_cam_pkt_t [NBLOAD_SIZE_MSB:0] cam_in; + load_cam_pkt_t [NBLOAD_SIZE_MSB:0] cam_in; logic [4:0] nonblock_load_rd; logic i1_nonblock_load_stall, i0_nonblock_load_stall; @@ -727,13 +727,13 @@ module dec_decode_ctl end end end - + logic cam_reset_same_dest_wb; - - assign cam_reset_same_dest_wb = wbd.i0v & wbd.i1v & (wbd.i0rd[4:0] == wbd.i1rd[4:0]) & + + assign cam_reset_same_dest_wb = wbd.i0v & wbd.i1v & (wbd.i0rd[4:0] == wbd.i1rd[4:0]) & wbd.i0load & nonblock_load_valid_wb & ~dec_tlu_i0_kill_writeb_wb & ~dec_tlu_i1_kill_writeb_wb; - - + + assign cam_write = lsu_nonblock_load_valid_dc3; assign cam_write_tag[NBLOAD_TAG_MSB:0] = lsu_nonblock_load_tag_dc3[NBLOAD_TAG_MSB:0]; @@ -747,28 +747,28 @@ module dec_decode_ctl logic [NBLOAD_SIZE_MSB:0] cam_inv_reset_val, cam_data_reset_val; logic i1_wen_wb, i0_wen_wb; - + // checks -`ifdef ASSERT_ON +`ifdef ASSERT_ON assert_dec_data_valid_data_error_onehot: assert #0 ($onehot0({lsu_nonblock_load_data_valid,lsu_nonblock_load_data_error})); - + assert_dec_cam_inv_reset_onehot: assert #0 ($onehot0(cam_inv_reset_val[NBLOAD_SIZE_MSB:0])); assert_dec_cam_data_reset_onehot: assert #0 ($onehot0(cam_data_reset_val[NBLOAD_SIZE_MSB:0])); -`endif - - // case of multiple loads to same dest ie. x1 ... you have to invalidate the older one +`endif + + // case of multiple loads to same dest ie. x1 ... you have to invalidate the older one for (genvar i=0; i used for clockgating for wb stage ctl logic rvdff #(1) divwbff (.*, .clk(active_clk), .din(exu_div_finish), .dout(div_wen_wb)); - + assign i0_result_e1[31:0] = exu_i0_result_e1[31:0]; - assign i1_result_e1[31:0] = exu_i1_result_e1[31:0]; + assign i1_result_e1[31:0] = exu_i1_result_e1[31:0]; // pipe the results down the pipe rvdffe #(32) i0e2resultff (.*, .en(i0_e2_data_en), .din(i0_result_e1[31:0]), .dout(i0_result_e2[31:0])); - rvdffe #(32) i1e2resultff (.*, .en(i1_e2_data_en), .din(i1_result_e1[31:0]), .dout(i1_result_e2[31:0])); + rvdffe #(32) i1e2resultff (.*, .en(i1_e2_data_en), .din(i1_result_e1[31:0]), .dout(i1_result_e2[31:0])); rvdffe #(32) i0e3resultff (.*, .en(i0_e3_data_en), .din(i0_result_e2[31:0]), .dout(i0_result_e3[31:0])); - rvdffe #(32) i1e3resultff (.*, .en(i1_e3_data_en), .din(i1_result_e2[31:0]), .dout(i1_result_e3[31:0])); + rvdffe #(32) i1e3resultff (.*, .en(i1_e3_data_en), .din(i1_result_e2[31:0]), .dout(i1_result_e3[31:0])); assign i0_result_e3_final[31:0] = (e3d.i0v & e3d.i0load) ? lsu_result_dc3[31:0] : (e3d.i0v & e3d.i0mul) ? exu_mul_result_e3[31:0] : i0_result_e3[31:0]; - assign i1_result_e3_final[31:0] = (e3d.i1v & e3d.i1load) ? lsu_result_dc3[31:0] : (e3d.i1v & e3d.i1mul) ? exu_mul_result_e3[31:0] : i1_result_e3[31:0]; + assign i1_result_e3_final[31:0] = (e3d.i1v & e3d.i1load) ? lsu_result_dc3[31:0] : (e3d.i1v & e3d.i1mul) ? exu_mul_result_e3[31:0] : i1_result_e3[31:0]; rvdffe #(32) i0e4resultff (.*, .en(i0_e4_data_en), .din(i0_result_e3_final[31:0]), .dout(i0_result_e4[31:0])); - rvdffe #(32) i1e4resultff (.*, .en(i1_e4_data_en), .din(i1_result_e3_final[31:0]), .dout(i1_result_e4[31:0])); - + rvdffe #(32) i1e4resultff (.*, .en(i1_e4_data_en), .din(i1_result_e3_final[31:0]), .dout(i1_result_e4[31:0])); + assign i0_result_e4_final[31:0] = - ( e4d.i0secondary) ? exu_i0_result_e4[31:0] : i0_result_e4[31:0]; - - assign i1_result_e4_final[31:0] = + ( e4d.i0secondary) ? exu_i0_result_e4[31:0] : i0_result_e4[31:0]; + + assign i1_result_e4_final[31:0] = (e4d.i1v & e4d.i1secondary) ? exu_i1_result_e4[31:0] : i1_result_e4[31:0]; rvdffe #(32) i0wbresultff (.*, .en(i0_wb_data_en), .din(i0_result_e4_final[31:0]), .dout(i0_result_wb_raw[31:0])); - rvdffe #(32) i1wbresultff (.*, .en(i1_wb_data_en), .din(i1_result_e4_final[31:0]), .dout(i1_result_wb_raw[31:0])); + rvdffe #(32) i1wbresultff (.*, .en(i1_wb_data_en), .din(i1_result_e4_final[31:0]), .dout(i1_result_wb_raw[31:0])); assign i0_result_wb[31:0] = (div_wen_wb) ? exu_div_result[31:0] : i0_result_wb_raw[31:0]; assign i1_result_wb[31:0] = i1_result_wb_raw[31:0]; logic [12:1] last_br_immed_e1, last_br_immed_e2; - + rvdffe #(12) e1brpcff (.*, .en(i0_e1_data_en), .din(last_br_immed_d[12:1] ), .dout(last_br_immed_e1[12:1])); rvdffe #(12) e2brpcff (.*, .en(i0_e2_data_en), .din(last_br_immed_e1[12:1]), .dout(last_br_immed_e2[12:1])); logic [31:0] i0_inst_d, i1_inst_d; - logic [31:0] i0_inst_e1, i1_inst_e1; + logic [31:0] i0_inst_e1, i1_inst_e1; logic [31:0] i0_inst_e2, i1_inst_e2; logic [31:0] i0_inst_e3, i1_inst_e3; logic [31:0] i0_inst_e4, i1_inst_e4; logic [31:0] i0_inst_wb, i1_inst_wb; - logic [31:0] i0_inst_wb1,i1_inst_wb1; + logic [31:0] i0_inst_wb1,i1_inst_wb1; logic [31:0] div_inst; - + // trace stuff rvdffe #(32) divinstff (.*, .en(i0_div_decode_d), .din(i0_inst_d[31:0]), .dout(div_inst[31:0])); - + assign i0_inst_d[31:0] = (dec_i0_pc4_d) ? i0[31:0] : {16'b0, dec_i0_cinst_d[15:0] }; - + rvdffe #(32) i0e1instff (.*, .en(i0_e1_data_en), .din(i0_inst_d[31:0]), .dout(i0_inst_e1[31:0])); - rvdffe #(32) i0e2instff (.*, .en(i0_e2_data_en), .din(i0_inst_e1[31:0]), .dout(i0_inst_e2[31:0])); + rvdffe #(32) i0e2instff (.*, .en(i0_e2_data_en), .din(i0_inst_e1[31:0]), .dout(i0_inst_e2[31:0])); rvdffe #(32) i0e3instff (.*, .en(i0_e3_data_en), .din(i0_inst_e2[31:0]), .dout(i0_inst_e3[31:0])); rvdffe #(32) i0e4instff (.*, .en(i0_e4_data_en), .din(i0_inst_e3[31:0]), .dout(i0_inst_e4[31:0])); rvdffe #(32) i0wbinstff (.*, .en(i0_wb_data_en | exu_div_finish), .din( (exu_div_finish) ? div_inst[31:0] : i0_inst_e4[31:0]), .dout(i0_inst_wb[31:0])); - rvdffe #(32) i0wb1instff (.*, .en(i0_wb1_data_en | div_wen_wb), .din(i0_inst_wb[31:0]), .dout(i0_inst_wb1[31:0])); + rvdffe #(32) i0wb1instff (.*, .en(i0_wb1_data_en | div_wen_wb), .din(i0_inst_wb[31:0]), .dout(i0_inst_wb1[31:0])); assign i1_inst_d[31:0] = (dec_i1_pc4_d) ? i1[31:0] : {16'b0, dec_i1_cinst_d[15:0] }; - + rvdffe #(32) i1e1instff (.*, .en(i1_e1_data_en), .din(i1_inst_d[31:0]), .dout(i1_inst_e1[31:0])); - rvdffe #(32) i1e2instff (.*, .en(i1_e2_data_en), .din(i1_inst_e1[31:0]), .dout(i1_inst_e2[31:0])); + rvdffe #(32) i1e2instff (.*, .en(i1_e2_data_en), .din(i1_inst_e1[31:0]), .dout(i1_inst_e2[31:0])); rvdffe #(32) i1e3instff (.*, .en(i1_e3_data_en), .din(i1_inst_e2[31:0]), .dout(i1_inst_e3[31:0])); rvdffe #(32) i1e4instff (.*, .en(i1_e4_data_en), .din(i1_inst_e3[31:0]), .dout(i1_inst_e4[31:0])); rvdffe #(32) i1wbinstff (.*, .en(i1_wb_data_en), .din(i1_inst_e4[31:0]), .dout(i1_inst_wb[31:0])); - rvdffe #(32) i1wb1instff (.*, .en(i1_wb1_data_en),.din(i1_inst_wb[31:0]), .dout(i1_inst_wb1[31:0])); + rvdffe #(32) i1wb1instff (.*, .en(i1_wb1_data_en),.din(i1_inst_wb[31:0]), .dout(i1_inst_wb1[31:0])); assign dec_i0_inst_wb1[31:0] = i0_inst_wb1[31:0]; - assign dec_i1_inst_wb1[31:0] = i1_inst_wb1[31:0]; + assign dec_i1_inst_wb1[31:0] = i1_inst_wb1[31:0]; logic [31:1] i0_pc_wb, i0_pc_wb1; - logic [31:1] i1_pc_wb1; + logic [31:1] i1_pc_wb1; rvdffe #(31) i0wbpcff (.*, .en(i0_wb_data_en | exu_div_finish), .din(dec_tlu_i0_pc_e4[31:1]), .dout(i0_pc_wb[31:1])); - rvdffe #(31) i0wb1pcff (.*, .en(i0_wb1_data_en | div_wen_wb), .din(i0_pc_wb[31:1]), .dout(i0_pc_wb1[31:1])); + rvdffe #(31) i0wb1pcff (.*, .en(i0_wb1_data_en | div_wen_wb), .din(i0_pc_wb[31:1]), .dout(i0_pc_wb1[31:1])); - rvdffe #(31) i1wb1pcff (.*, .en(i1_wb1_data_en),.din(i1_pc_wb[31:1]), .dout(i1_pc_wb1[31:1])); + rvdffe #(31) i1wb1pcff (.*, .en(i1_wb1_data_en),.din(i1_pc_wb[31:1]), .dout(i1_pc_wb1[31:1])); assign dec_i0_pc_wb1[31:1] = i0_pc_wb1[31:1]; - assign dec_i1_pc_wb1[31:1] = i1_pc_wb1[31:1]; - + assign dec_i1_pc_wb1[31:1] = i1_pc_wb1[31:1]; + // end trace - + // pipe the pc's down the pipe assign i0_pc_e1[31:1] = exu_i0_pc_e1[31:1]; - assign i1_pc_e1[31:1] = exu_i1_pc_e1[31:1]; - + assign i1_pc_e1[31:1] = exu_i1_pc_e1[31:1]; + rvdffe #(31) i0e2pcff (.*, .en(i0_e2_data_en), .din(i0_pc_e1[31:1]), .dout(i0_pc_e2[31:1])); rvdffe #(31) i0e3pcff (.*, .en(i0_e3_data_en), .din(i0_pc_e2[31:1]), .dout(i0_pc_e3[31:1])); rvdffe #(31) i0e4pcff (.*, .en(i0_e4_data_en), .din(i0_pc_e3[31:1]), .dout(i0_pc_e4[31:1])); @@ -2287,17 +2287,17 @@ end : cam_array rvdffe #(31) i1e4pcff (.*, .en(i1_e4_data_en), .din(i1_pc_e3[31:1]), .dout(i1_pc_e4[31:1])); assign dec_i0_pc_e3[31:1] = i0_pc_e3[31:1]; - assign dec_i1_pc_e3[31:1] = i1_pc_e3[31:1]; - - + assign dec_i1_pc_e3[31:1] = i1_pc_e3[31:1]; + + assign dec_tlu_i0_pc_e4[31:1] = (exu_div_finish) ? div_pc[31:1] : i0_pc_e4[31:1]; - assign dec_tlu_i1_pc_e4[31:1] = i1_pc_e4[31:1]; - + assign dec_tlu_i1_pc_e4[31:1] = i1_pc_e4[31:1]; + logic [31:1] last_pc_e2; // generate the correct npc for correct br predictions assign last_pc_e2[31:1] = (e2d.i1valid) ? i1_pc_e2[31:1] : i0_pc_e2[31:1]; - + rvbradder ibradder_correct ( .pc(last_pc_e2[31:1]), .offset(last_br_immed_e2[12:1]), @@ -2306,12 +2306,12 @@ end : cam_array - // needed for debug triggers - rvdffe #(31) i1wbpcff (.*, .en(i1_wb_data_en), .din(dec_tlu_i1_pc_e4[31:1]), .dout(i1_pc_wb[31:1])); - + // needed for debug triggers + rvdffe #(31) i1wbpcff (.*, .en(i1_wb_data_en), .din(dec_tlu_i1_pc_e4[31:1]), .dout(i1_pc_wb[31:1])); + // bit 9 is priority match, bit 0 lowest priority, i1_e1, i0_e1, i1_e2, ... i1_wb, i0_wb - + assign i0_rs1bypass[9:0] = { i0_rs1_depth_d[3:0] == 4'd1 & i0_rs1_class_d.alu, i0_rs1_depth_d[3:0] == 4'd2 & i0_rs1_class_d.alu, i0_rs1_depth_d[3:0] == 4'd3 & i0_rs1_class_d.alu, @@ -2322,7 +2322,7 @@ end : cam_array i0_rs1_depth_d[3:0] == 4'd8 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul | i0_rs1_class_d.sec), i0_rs1_depth_d[3:0] == 4'd9 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul | i0_rs1_class_d.sec), i0_rs1_depth_d[3:0] == 4'd10 & (i0_rs1_class_d.alu | i0_rs1_class_d.load | i0_rs1_class_d.mul | i0_rs1_class_d.sec) }; - + assign i0_rs2bypass[9:0] = { i0_rs2_depth_d[3:0] == 4'd1 & i0_rs2_class_d.alu, i0_rs2_depth_d[3:0] == 4'd2 & i0_rs2_class_d.alu, @@ -2334,7 +2334,7 @@ end : cam_array i0_rs2_depth_d[3:0] == 4'd8 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul | i0_rs2_class_d.sec), i0_rs2_depth_d[3:0] == 4'd9 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul | i0_rs2_class_d.sec), i0_rs2_depth_d[3:0] == 4'd10 & (i0_rs2_class_d.alu | i0_rs2_class_d.load | i0_rs2_class_d.mul | i0_rs2_class_d.sec) }; - + assign i1_rs1bypass[9:0] = { i1_rs1_depth_d[3:0] == 4'd1 & i1_rs1_class_d.alu, i1_rs1_depth_d[3:0] == 4'd2 & i1_rs1_class_d.alu, @@ -2346,7 +2346,7 @@ end : cam_array i1_rs1_depth_d[3:0] == 4'd8 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul | i1_rs1_class_d.sec), i1_rs1_depth_d[3:0] == 4'd9 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul | i1_rs1_class_d.sec), i1_rs1_depth_d[3:0] == 4'd10 & (i1_rs1_class_d.alu | i1_rs1_class_d.load | i1_rs1_class_d.mul | i1_rs1_class_d.sec) }; - + assign i1_rs2bypass[9:0] = { i1_rs2_depth_d[3:0] == 4'd1 & i1_rs2_class_d.alu, i1_rs2_depth_d[3:0] == 4'd2 & i1_rs2_class_d.alu, @@ -2358,13 +2358,13 @@ end : cam_array i1_rs2_depth_d[3:0] == 4'd8 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul | i1_rs2_class_d.sec), i1_rs2_depth_d[3:0] == 4'd9 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul | i1_rs2_class_d.sec), i1_rs2_depth_d[3:0] == 4'd10 & (i1_rs2_class_d.alu | i1_rs2_class_d.load | i1_rs2_class_d.mul | i1_rs2_class_d.sec) }; - + assign dec_i0_rs1_bypass_en_d = |i0_rs1bypass[9:0]; assign dec_i0_rs2_bypass_en_d = |i0_rs2bypass[9:0]; assign dec_i1_rs1_bypass_en_d = |i1_rs1bypass[9:0]; - assign dec_i1_rs2_bypass_en_d = |i1_rs2bypass[9:0]; + assign dec_i1_rs2_bypass_en_d = |i1_rs2bypass[9:0]; + - assign i0_rs1_bypass_data_d[31:0] = ({32{i0_rs1bypass[9]}} & i1_result_e1[31:0]) | ({32{i0_rs1bypass[8]}} & i0_result_e1[31:0]) | @@ -2376,7 +2376,7 @@ end : cam_array ({32{i0_rs1bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i0_rs1bypass[1]}} & i1_result_wb[31:0]) | ({32{i0_rs1bypass[0]}} & i0_result_wb[31:0]); - + assign i0_rs2_bypass_data_d[31:0] = ({32{i0_rs2bypass[9]}} & i1_result_e1[31:0]) | ({32{i0_rs2bypass[8]}} & i0_result_e1[31:0]) | @@ -2388,7 +2388,7 @@ end : cam_array ({32{i0_rs2bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i0_rs2bypass[1]}} & i1_result_wb[31:0]) | ({32{i0_rs2bypass[0]}} & i0_result_wb[31:0]); - + assign i1_rs1_bypass_data_d[31:0] = ({32{i1_rs1bypass[9]}} & i1_result_e1[31:0]) | ({32{i1_rs1bypass[8]}} & i0_result_e1[31:0]) | ({32{i1_rs1bypass[7]}} & i1_result_e2[31:0]) | @@ -2399,7 +2399,7 @@ end : cam_array ({32{i1_rs1bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i1_rs1bypass[1]}} & i1_result_wb[31:0]) | ({32{i1_rs1bypass[0]}} & i0_result_wb[31:0]); - + assign i1_rs2_bypass_data_d[31:0] = ({32{i1_rs2bypass[9]}} & i1_result_e1[31:0]) | ({32{i1_rs2bypass[8]}} & i0_result_e1[31:0]) | @@ -2411,8 +2411,8 @@ end : cam_array ({32{i1_rs2bypass[2]}} & i0_result_e4_final[31:0]) | ({32{i1_rs2bypass[1]}} & i1_result_wb[31:0]) | ({32{i1_rs2bypass[0]}} & i0_result_wb[31:0]); - - + + endmodule // file "decode" is human readable file that has all of the instruction decodes defined and is part of git repo @@ -2439,8 +2439,8 @@ module dec_dec_ctl ); logic [31:0] i; - - + + assign i[31:0] = inst[31:0]; @@ -2604,5 +2604,5 @@ assign out.legal = (!i[31]&!i[30]&i[29]&i[28]&!i[27]&!i[26]&!i[25]&!i[24]&!i[23] i[13]&!i[6]&!i[5]&i[4]&!i[3]&i[1]&i[0]) | (!i[14]&!i[12]&!i[6]&!i[4] &!i[3]&!i[2]&i[1]&i[0]) | (!i[6]&i[4]&!i[3]&i[2]&i[1]&i[0]); - + endmodule diff --git a/design/dec/dec_gpr_ctl.sv b/design/dec/dec_gpr_ctl.sv index d5b0d2a..53c01b4 100644 --- a/design/dec/dec_gpr_ctl.sv +++ b/design/dec/dec_gpr_ctl.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -14,7 +14,7 @@ // limitations under the License. module dec_gpr_ctl #(parameter GPR_BANKS = 1, - GPR_BANKS_LOG2 = 1) + GPR_BANKS_LOG2 = 1) ( input logic active_clk, @@ -30,10 +30,10 @@ module dec_gpr_ctl #(parameter GPR_BANKS = 1, input logic [4:0] waddr0, // logical write addresses input logic [4:0] waddr1, - input logic [4:0] waddr2, + input logic [4:0] waddr2, input logic wen0, // write enables - input logic wen1, + input logic wen1, input logic wen2, input logic [31:0] wd0, // write data @@ -60,55 +60,55 @@ module dec_gpr_ctl #(parameter GPR_BANKS = 1, logic [31:1] gpr_wr_en; logic [GPR_BANKS-1:0][31:1] gpr_bank_wr_en; logic [GPR_BANKS_LOG2-1:0] gpr_bank_id; - + //assign gpr_bank_id[GPR_BANKS_LOG2-1:0] = '0; - rvdffs #(GPR_BANKS_LOG2) bankid_ff (.*, .clk(active_clk), .en(wen_bank_id), .din(wr_bank_id[GPR_BANKS_LOG2-1:0]), .dout(gpr_bank_id[GPR_BANKS_LOG2-1:0])); - - // GPR Write Enables for power savings + rvdffs #(GPR_BANKS_LOG2) bankid_ff (.*, .clk(active_clk), .en(wen_bank_id), .din(wr_bank_id[GPR_BANKS_LOG2-1:0]), .dout(gpr_bank_id[GPR_BANKS_LOG2-1:0])); + + // GPR Write Enables for power savings assign gpr_wr_en[31:1] = (w0v[31:1] | w1v[31:1] | w2v[31:1]); for (genvar i=0; i csrrw %x0, %csr, %x0 {csr[11:0],00000001000001110011} - // abstract memory command not done here - assign debug_valid = dbg_cmd_valid & (dbg_cmd_type[1:0] != 2'h2); - + // abstract memory command not done here + assign debug_valid = dbg_cmd_valid & (dbg_cmd_type[1:0] != 2'h2); + assign debug_read = debug_valid & ~dbg_cmd_write; - assign debug_write = debug_valid & dbg_cmd_write; + assign debug_write = debug_valid & dbg_cmd_write; assign debug_read_gpr = debug_read & (dbg_cmd_type[1:0]==2'h0); - assign debug_write_gpr = debug_write & (dbg_cmd_type[1:0]==2'h0); + assign debug_write_gpr = debug_write & (dbg_cmd_type[1:0]==2'h0); assign debug_read_csr = debug_read & (dbg_cmd_type[1:0]==2'h1); assign debug_write_csr = debug_write & (dbg_cmd_type[1:0]==2'h1); - assign dreg[4:0] = dbg_cmd_addr[4:0]; - assign dcsr[11:0] = dbg_cmd_addr[11:0]; - + assign dreg[4:0] = dbg_cmd_addr[4:0]; + assign dcsr[11:0] = dbg_cmd_addr[11:0]; + assign ib0_debug_in[31:0] = ({32{debug_read_gpr}} & {12'b000000000000,dreg[4:0],15'b110000000110011}) | ({32{debug_write_gpr}} & {20'b00000000000000000110,dreg[4:0],7'b0110011}) | @@ -404,38 +404,38 @@ module dec_ib_ctl // special fence csr for use only in debug mode logic debug_fence_in; - + assign debug_fence_in = debug_write_csr & (dcsr[11:0] == 12'h7c4); - - rvdff #(1) debug_fence_ff (.*, .clk(free_clk), .din(debug_fence_in), .dout(dec_debug_fence_d)); - - + + rvdff #(1) debug_fence_ff (.*, .clk(free_clk), .din(debug_fence_in), .dout(dec_debug_fence_d)); + + assign ib0_in[31:0] = ({32{write_i0_ib0}} & ((debug_valid) ? ib0_debug_in[31:0] : ifu_i0_instr[31:0])) | ({32{shift_ib1_ib0}} & ib1[31:0]) | ({32{shift_ib2_ib0}} & ib2[31:0]); - + rvdffe #(32) ib0ff (.*, .en(ibwrite[0]), .din(ib0_in[31:0]), .dout(ib0[31:0])); assign dec_ib3_valid_d = ibval[3]; assign dec_ib2_valid_d = ibval[2]; assign dec_ib1_valid_d = ibval[1]; - assign dec_ib0_valid_d = ibval[0]; - + assign dec_ib0_valid_d = ibval[0]; + assign dec_i0_instr_d[31:0] = ib0[31:0]; - assign dec_i1_instr_d[31:0] = ib1[31:0]; + assign dec_i1_instr_d[31:0] = ib1[31:0]; assign dec_i0_brp = bp0; - assign dec_i1_brp = bp1; - - + assign dec_i1_brp = bp1; + + assign shift1 = dec_i0_decode_d & ~dec_i1_decode_d; assign shift2 = dec_i0_decode_d & dec_i1_decode_d; assign shift0 = ~dec_i0_decode_d; - - + + // compute shifted ib valids to determine where to write assign shift_ibval[3:0] = ({4{shift1}} & {1'b0, ibval[3:1] }) | ({4{shift2}} & {2'b0, ibval[3:2]}) | @@ -445,7 +445,7 @@ module dec_ib_ctl assign write_i0_ib1 = shift_ibval[0] & ~shift_ibval[1] & ifu_i0_val; assign write_i0_ib2 = shift_ibval[1] & ~shift_ibval[2] & ifu_i0_val; assign write_i0_ib3 = shift_ibval[2] & ~shift_ibval[3] & ifu_i0_val; - + assign write_i1_ib1 = ~shift_ibval[0] & ifu_i1_val; assign write_i1_ib2 = shift_ibval[0] & ~shift_ibval[1] & ifu_i1_val; assign write_i1_ib3 = shift_ibval[1] & ~shift_ibval[2] & ifu_i1_val; @@ -453,11 +453,11 @@ module dec_ib_ctl assign shift_ib1_ib0 = shift1 & ibval[1]; assign shift_ib2_ib1 = shift1 & ibval[2]; - assign shift_ib3_ib2 = shift1 & ibval[3]; - + assign shift_ib3_ib2 = shift1 & ibval[3]; + assign shift_ib2_ib0 = shift2 & ibval[2]; assign shift_ib3_ib1 = shift2 & ibval[3]; - - + + endmodule diff --git a/design/dec/dec_tlu_ctl.sv b/design/dec/dec_tlu_ctl.sv index 9e77453..4ca46a8 100644 --- a/design/dec/dec_tlu_ctl.sv +++ b/design/dec/dec_tlu_ctl.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,9 +17,9 @@ //******************************************************************************** // dec_tlu_ctl.sv // -// +// // Function: CSRs, Commit/WB, flushing, exceptions, interrupts -// Comments: +// Comments: // //******************************************************************************** @@ -31,10 +31,10 @@ module dec_tlu_ctl input logic free_clk, input logic rst_l, input logic scan_mode, - + input logic [31:1] rst_vec, // reset vector, from core pins input logic nmi_int, // nmi pin - input logic [31:1] nmi_vec, // nmi vector + input logic [31:1] nmi_vec, // nmi vector input logic i_cpu_halt_req, // Asynchronous Halt request to CPU input logic i_cpu_run_req, // Asynchronous Restart request to CPU @@ -45,7 +45,7 @@ module dec_tlu_ctl input logic ifu_pmu_ic_miss, // icache miss input logic ifu_pmu_ic_hit, // icache hit input logic ifu_pmu_bus_error, // Instruction side bus error - input logic ifu_pmu_bus_busy, // Instruction side bus busy + input logic ifu_pmu_bus_busy, // Instruction side bus busy input logic ifu_pmu_bus_trxn, // Instruction side bus transaction input logic [1:0] dec_pmu_instr_decoded, // decoded instructions input logic dec_pmu_decode_stall, // decode stall @@ -54,13 +54,13 @@ module dec_tlu_ctl input logic lsu_freeze_dc3, // lsu freeze stall input logic lsu_store_stall_any, // SB or WB is full, stall decode input logic dma_dccm_stall_any, // DMA stall of lsu - input logic dma_iccm_stall_any, // DMA stall of ifu + input logic dma_iccm_stall_any, // DMA stall of ifu input logic exu_pmu_i0_br_misp, // pipe 0 branch misp input logic exu_pmu_i0_br_ataken, // pipe 0 branch actual taken - input logic exu_pmu_i0_pc4, // pipe 0 4 byte branch - input logic exu_pmu_i1_br_misp, // pipe 1 branch misp + input logic exu_pmu_i0_pc4, // pipe 0 4 byte branch + input logic exu_pmu_i1_br_misp, // pipe 1 branch misp input logic exu_pmu_i1_br_ataken, // pipe 1 branch actual taken - input logic exu_pmu_i1_pc4, // pipe 1 4 byte branch + input logic exu_pmu_i1_pc4, // pipe 1 4 byte branch input logic lsu_pmu_bus_trxn, // D side bus transaction input logic lsu_pmu_bus_misaligned, // D side bus misaligned input logic lsu_pmu_bus_error, // D side bus error @@ -68,7 +68,7 @@ module dec_tlu_ctl input logic iccm_dma_sb_error, // I side dma single bit error - + input lsu_error_pkt_t lsu_error_pkt_dc3, // lsu precise exception/error packet input logic dec_pause_state, // Pause counter not zero @@ -78,11 +78,11 @@ module dec_tlu_ctl input logic lsu_freeze_external_ints_dc3, // load to side effect region input logic dec_csr_wen_unq_d, // valid csr with write - for csr legal - input logic dec_csr_any_unq_d, // valid csr - for csr legal - input logic dec_csr_wen_wb, // csr write enable at wb - input logic [11:0] dec_csr_rdaddr_d, // read address for csr + input logic dec_csr_any_unq_d, // valid csr - for csr legal + input logic dec_csr_wen_wb, // csr write enable at wb + input logic [11:0] dec_csr_rdaddr_d, // read address for csr input logic [11:0] dec_csr_wraddr_wb, // write address for csr - input logic [31:0] dec_csr_wrdata_wb, // csr write data at wb + input logic [31:0] dec_csr_wrdata_wb, // csr write data at wb input logic dec_csr_stall_int_ff, // csr is mie/mstatus input logic dec_tlu_i0_valid_e4, // pipe 0 op at e4 is valid @@ -113,8 +113,8 @@ module dec_tlu_ctl input logic exu_i0_br_valid_e4, // valid input logic exu_i0_br_mp_e4, // mispredict input logic exu_i0_br_middle_e4, // middle of bank - input logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // FGHR when predicted - + input logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // FGHR when predicted + // branch info from pipe1 for errors or counter updates input logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] exu_i1_br_index_e4, // index input logic [1:0] exu_i1_br_hist_e4, // history @@ -174,20 +174,20 @@ module dec_tlu_ctl output logic o_debug_mode_status, // Core to the PMU that core is in debug mode. When core is in debug mode, the PMU should refrain from sendng a halt or run request output logic [3:0] dec_tlu_meicurpl, // to PIC output logic [3:0] dec_tlu_meipt, // to PIC - + output br_tlu_pkt_t dec_tlu_br0_wb_pkt, // branch pkt to bp output br_tlu_pkt_t dec_tlu_br1_wb_pkt, // branch pkt to bp output logic [31:0] dec_csr_rddata_d, // csr read data at wb output logic dec_csr_legal_d, // csr indicates legal operation - output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state - output logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state + output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state + output logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state output logic dec_tlu_flush_lower_wb, // commit has a flush (exception, int, mispredict at e4) output logic [31:1] dec_tlu_flush_path_wb, // flush pc output logic dec_tlu_fence_i_wb, // flush is a fence_i rfnpc, flush icache - + output logic dec_tlu_presync_d, // CSR read needs to be presync'd output logic dec_tlu_postsync_d, // CSR needs to be presync'd @@ -209,7 +209,7 @@ module dec_tlu_ctl output logic dec_tlu_int_valid_wb1, // pipe 2 int valid output logic [4:0] dec_tlu_exc_cause_wb1, // exception or int cause output logic [31:0] dec_tlu_mtval_wb1, // MTVAL value - + // feature disable from mfdc output logic dec_tlu_dual_issue_disable, // disable dual issue output logic dec_tlu_core_ecc_disable, // disable core ECC @@ -233,14 +233,14 @@ module dec_tlu_ctl ); - logic dec_csr_wen_wb_mod, clk_override, e4e5_int_clk, nmi_lsu_load_type, nmi_lsu_store_type, nmi_int_detected_f, nmi_lsu_load_type_f, - nmi_lsu_store_type_f, allow_dbg_halt_csr_write, dbg_cmd_done_ns, i_cpu_run_req_d1_raw, debug_mode_status, lsu_single_ecc_error_wb, - i0_mp_e4, i1_mp_e4, sel_npc_e4, sel_npc_wb, ce_int, mtval_capture_lsu_wb, wr_mdeau_wb, micect_cout_nc, miccmect_cout_nc, + logic dec_csr_wen_wb_mod, clk_override, e4e5_int_clk, nmi_lsu_load_type, nmi_lsu_store_type, nmi_int_detected_f, nmi_lsu_load_type_f, + nmi_lsu_store_type_f, allow_dbg_halt_csr_write, dbg_cmd_done_ns, i_cpu_run_req_d1_raw, debug_mode_status, lsu_single_ecc_error_wb, + i0_mp_e4, i1_mp_e4, sel_npc_e4, sel_npc_wb, ce_int, mtval_capture_lsu_wb, wr_mdeau_wb, micect_cout_nc, miccmect_cout_nc, mdccmect_cout_nc, nmi_in_debug_mode, dpc_capture_npc, dpc_capture_pc, tdata_load, tdata_opcode, tdata_action, perfcnt_halted; - + logic reset_delayed, reset_detect, reset_detected; - logic wr_mstatus_wb, wr_mtvec_wb, wr_mie_wb, wr_mcyclel_wb, wr_mcycleh_wb, + logic wr_mstatus_wb, wr_mtvec_wb, wr_mie_wb, wr_mcyclel_wb, wr_mcycleh_wb, wr_minstretl_wb, wr_minstreth_wb, wr_mscratch_wb, wr_mepc_wb, wr_mcause_wb, wr_mtval_wb, wr_mrac_wb, wr_meihap_wb, wr_meicurpl_wb, wr_meipt_wb, wr_dcsr_wb, wr_dpc_wb, wr_meicidpl_wb, wr_meivt_wb, wr_meicpct_wb, wr_micect_wb, wr_miccmect_wb, @@ -255,14 +255,14 @@ module dec_tlu_ctl logic [1:0] mstatus_ns, mstatus; logic mstatus_mie_ns; logic [30:0] mtvec_ns, mtvec; - logic [15:2] dcsr_ns, dcsr; + logic [15:2] dcsr_ns, dcsr; logic [3:0] mip_ns, mip; logic [3:0] mie_ns, mie; logic [31:0] mcyclel_ns, mcyclel; logic [31:0] mcycleh_ns, mcycleh; logic [31:0] minstretl_ns, minstretl; logic [31:0] minstreth_ns, minstreth; - logic [31:0] micect_ns, micect, miccmect_ns, miccmect, mdccmect_ns, mdccmect; + logic [31:0] micect_ns, micect, miccmect_ns, miccmect, mdccmect_ns, mdccmect; logic [26:0] micect_inc, miccmect_inc, mdccmect_inc; logic [31:0] mscratch; logic [31:0] mhpmc3, mhpmc3_ns, mhpmc4, mhpmc4_ns, mhpmc5, mhpmc5_ns, mhpmc6, mhpmc6_ns; @@ -294,12 +294,12 @@ module dec_tlu_ctl `ifdef RV_ICACHE_ECC logic [9:0] dicad1_ns, dicad1; `else - logic [1:0] dicad1_ns, dicad1; + logic [1:0] dicad1_ns, dicad1; `endif logic ebreak_e4, ebreak_to_debug_mode_e4, ecall_e4, illegal_e4, illegal_e4_qual, mret_e4, inst_acc_e4, fence_i_e4, ic_perr_e4, iccm_sbecc_e4, ebreak_to_debug_mode_wb, kill_ebreak_count_wb, inst_acc_second_e4; logic ebreak_wb, illegal_wb, illegal_raw_wb, inst_acc_wb, inst_acc_second_wb, fence_i_wb, ic_perr_wb, iccm_sbecc_wb; - logic ce_int_ready, ext_int_ready, timer_int_ready, mhwakeup_ready, + logic ce_int_ready, ext_int_ready, timer_int_ready, mhwakeup_ready, take_ext_int, take_ce_int, take_timer_int, take_nmi, take_nmi_wb; logic i0_exception_valid_e4, interrupt_valid, i0_exception_valid_wb, interrupt_valid_wb, exc_or_int_valid, exc_or_int_valid_wb, mdccme_ce_req, miccme_ce_req, mice_ce_req; logic synchronous_flush_e4; @@ -321,8 +321,8 @@ module dec_tlu_ctl logic lsu_i0_rfpc_dc4, lsu_i1_rfpc_dc4; logic dec_tlu_br0_error_e4, dec_tlu_br0_start_error_e4, dec_tlu_br0_v_e4; logic dec_tlu_br1_error_e4, dec_tlu_br1_start_error_e4, dec_tlu_br1_v_e4; - logic lsu_i0_exc_dc4, lsu_i1_exc_dc4, lsu_i0_exc_dc4_raw, lsu_i1_exc_dc4_raw, lsu_exc_ma_dc4, lsu_exc_acc_dc4, lsu_exc_st_dc4, - lsu_exc_valid_e4, lsu_exc_valid_e4_raw, lsu_exc_valid_wb, lsu_i0_exc_wb, + logic lsu_i0_exc_dc4, lsu_i1_exc_dc4, lsu_i0_exc_dc4_raw, lsu_i1_exc_dc4_raw, lsu_exc_ma_dc4, lsu_exc_acc_dc4, lsu_exc_st_dc4, + lsu_exc_valid_e4, lsu_exc_valid_e4_raw, lsu_exc_valid_wb, lsu_i0_exc_wb, block_interrupts, lsu_block_interrupts_dc3, lsu_block_interrupts_e4; logic tlu_i0_commit_cmt, tlu_i1_commit_cmt; @@ -331,8 +331,8 @@ module dec_tlu_ctl dbg_tlu_halted, core_empty, lsu_idle_any_f, ifu_miss_state_idle_f, resume_ack_ns, dbg_halt_req_f, dbg_resume_req_f, enter_dbg_halt_req, dcsr_single_step_done, dcsr_single_step_done_f, dbg_halt_req_d1, dbg_halt_req_ns, dcsr_single_step_running, dcsr_single_step_running_f, internal_dbg_halt_timers; - - logic [3:0] i0_trigger_e4, i1_trigger_e4, trigger_action, trigger_enabled, + + logic [3:0] i0_trigger_e4, i1_trigger_e4, trigger_action, trigger_enabled, i0_trigger_chain_masked_e4, i1_trigger_chain_masked_e4; logic [2:0] trigger_chain; logic i0_trigger_hit_e4, i0_trigger_action_e4, @@ -340,7 +340,7 @@ module dec_tlu_ctl mepc_trigger_hit_sel_pc_e4, mepc_trigger_hit_sel_pc_wb; logic i1_trigger_hit_e4, i1_trigger_action_e4; - logic [3:0] update_hit_bit_e4, update_hit_bit_wb, i0_iside_trigger_has_pri_e4, i1_iside_trigger_has_pri_e4, + logic [3:0] update_hit_bit_e4, update_hit_bit_wb, i0_iside_trigger_has_pri_e4, i1_iside_trigger_has_pri_e4, i0trigger_qual_e4, i1trigger_qual_e4, i0_lsu_trigger_has_pri_e4, i1_lsu_trigger_has_pri_e4; logic cpu_halt_status, cpu_halt_ack, cpu_run_ack, ext_halt_pulse, i_cpu_halt_req_d1, i_cpu_run_req_d1; @@ -349,20 +349,20 @@ module dec_tlu_ctl logic [8:0] mcgc; logic [10:0] mfdc; logic i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, pmu_fw_halt_req_ns, pmu_fw_halt_req_f, - fw_halt_req, enter_pmu_fw_halt_req, pmu_fw_tlu_halted, pmu_fw_tlu_halted_f, internal_pmu_fw_halt_mode, + fw_halt_req, enter_pmu_fw_halt_req, pmu_fw_tlu_halted, pmu_fw_tlu_halted_f, internal_pmu_fw_halt_mode, internal_pmu_fw_halt_mode_f; logic dcsr_single_step_running_ff; logic nmi_int_delayed, nmi_int_detected; logic [3:0] trigger_execute, trigger_data, trigger_store; - - + + assign clk_override = dec_tlu_dec_clk_override; - + // Async inputs to the core have to be sync'd to the core clock. logic nmi_int_sync, timer_int_sync, i_cpu_halt_req_sync, i_cpu_run_req_sync; - rvsyncss #(4) syncro_ff(.*, - .clk(free_clk), - .din ({nmi_int, timer_int, i_cpu_halt_req, i_cpu_run_req}), + rvsyncss #(4) syncro_ff(.*, + .clk(free_clk), + .din ({nmi_int, timer_int, i_cpu_halt_req, i_cpu_run_req}), .dout({nmi_int_sync, timer_int_sync, i_cpu_halt_req_sync, i_cpu_run_req_sync})); // for CSRs that have inpipe writes only @@ -380,8 +380,8 @@ module dec_tlu_ctl rvclkhdr e4e5_int_cgc ( .en(e4e5_valid | internal_dbg_halt_mode_f | i_cpu_run_req_d1 | interrupt_valid | interrupt_valid_wb | reset_delayed | pause_expired_e4 | pause_expired_wb | clk_override), .l1clk(e4e5_int_clk), .* ); - - rvdff #(6) freeff (.*, .clk(free_clk), .din({e4_valid, lsu_block_interrupts_dc3, internal_dbg_halt_mode, tlu_flush_lower_e4, tlu_i0_kill_writeb_e4, tlu_i1_kill_writeb_e4 }), + + rvdff #(6) freeff (.*, .clk(free_clk), .din({e4_valid, lsu_block_interrupts_dc3, internal_dbg_halt_mode, tlu_flush_lower_e4, tlu_i0_kill_writeb_e4, tlu_i1_kill_writeb_e4 }), .dout({e5_valid, lsu_block_interrupts_e4, internal_dbg_halt_mode_f, tlu_flush_lower_wb, dec_tlu_i0_kill_writeb_wb, dec_tlu_i1_kill_writeb_wb})); @@ -392,7 +392,7 @@ module dec_tlu_ctl // Filter subsequent bus errors after the first, until the lock on MDSEAC is cleared assign nmi_lsu_detected = ~mdseac_locked_f & (lsu_imprecise_error_load_any | lsu_imprecise_error_store_any); - + assign nmi_int_detected = (nmi_int_sync & ~nmi_int_delayed) | nmi_lsu_detected | (nmi_int_detected_f & ~take_nmi_wb); // if the first nmi is a lsu type, note it. If there's already an nmi pending, ignore assign nmi_lsu_load_type = (nmi_lsu_detected & lsu_imprecise_error_load_any & ~(nmi_int_detected_f & ~take_nmi_wb)) | (nmi_lsu_load_type_f & ~take_nmi_wb); @@ -409,18 +409,18 @@ module dec_tlu_ctl `define MIE_MTIE 1 `define MIE_MSIE 0 -`define DCSR_EBREAKM 15 -`define DCSR_STEPIE 11 -`define DCSR_STOPC 10 -//`define DCSR_STOPT 9 -`define DCSR_STEP 2 +`define DCSR_EBREAKM 15 +`define DCSR_STEPIE 11 +`define DCSR_STOPC 10 +//`define DCSR_STOPT 9 +`define DCSR_STEP 2 - // HALT + // HALT // dbg/pmu/fw requests halt, service as soon as lsu is not blocking interrupts assign take_halt = (dbg_halt_req_f | pmu_fw_halt_req_f) & ~lsu_block_interrupts_e4 & ~synchronous_flush_e4 & ~mret_e4 & ~halt_taken_f & ~dec_tlu_flush_noredir_wb & ~take_reset; - + // hold after we take a halt, so we don't keep taking halts assign halt_taken = (dec_tlu_flush_noredir_wb & ~dec_tlu_flush_pause_wb) | (halt_taken_f & ~dbg_tlu_halted_f & ~pmu_fw_tlu_halted_f); @@ -431,9 +431,9 @@ module dec_tlu_ctl //-------------------------------------------------------------------------------- // Debug start // - + assign enter_dbg_halt_req = (~internal_dbg_halt_mode_f & dbg_halt_req) | dcsr_single_step_done_f | trigger_hit_dmode_wb | ebreak_to_debug_mode_wb; - + // internal to tlu, used for holding off interrupts, etc. // assign internal_dbg_halt_mode = dbg_halt_req_ns | halt_taken | dbg_tlu_halted_f; @@ -441,11 +441,11 @@ module dec_tlu_ctl assign internal_dbg_halt_mode = dbg_halt_req_ns | (internal_dbg_halt_mode_f & ~(dbg_resume_req_f & ~dcsr[`DCSR_STEP])); // dbg halt can access csrs as long as we are not stepping assign allow_dbg_halt_csr_write = internal_dbg_halt_mode_f & ~dcsr_single_step_running_f; - + // hold dbg_halt_req_ns high until we enter debug halt assign dbg_halt_req_ns = enter_dbg_halt_req | (dbg_halt_req_f & ~dbg_tlu_halted); - + assign dbg_tlu_halted = (dbg_halt_req_f & core_empty & halt_taken) | (dbg_tlu_halted_f & ~dbg_resume_req_f); assign resume_ack_ns = (dbg_resume_req_f & dbg_tlu_halted_f); @@ -455,17 +455,17 @@ module dec_tlu_ctl assign dcsr_single_step_running = (dbg_resume_req_f & dcsr[`DCSR_STEP]) | (dcsr_single_step_running_f & ~dcsr_single_step_done_f); assign dbg_cmd_done_ns = dec_tlu_i0_valid_e4 & dec_tlu_dbg_halted; - + // used to hold off commits after an in-pipe debug mode request (triggers, DCSR) assign request_debug_mode_e4 = (trigger_hit_dmode_e4 | ebreak_to_debug_mode_e4) | (request_debug_mode_wb & ~dec_tlu_flush_lower_wb); assign request_debug_mode_done = (request_debug_mode_wb | request_debug_mode_done_f) & ~dbg_tlu_halted_f; - rvdff #(22) halt_ff (.*, .clk(free_clk), .din({halt_taken, take_halt, lsu_idle_any, ifu_miss_state_idle, dbg_tlu_halted, - resume_ack_ns, dbg_cmd_done_ns, dbg_halt_req_ns, dbg_resume_req, trigger_hit_dmode_e4, + rvdff #(22) halt_ff (.*, .clk(free_clk), .din({halt_taken, take_halt, lsu_idle_any, ifu_miss_state_idle, dbg_tlu_halted, + resume_ack_ns, dbg_cmd_done_ns, dbg_halt_req_ns, dbg_resume_req, trigger_hit_dmode_e4, dcsr_single_step_done, dbg_halt_req, update_hit_bit_e4[3:0], dec_tlu_wr_pause_wb, dec_pause_state, - request_debug_mode_e4, request_debug_mode_done, dcsr_single_step_running, dcsr_single_step_running_f}), - .dout({halt_taken_f, take_halt_f, lsu_idle_any_f, ifu_miss_state_idle_f, dbg_tlu_halted_f, + request_debug_mode_e4, request_debug_mode_done, dcsr_single_step_running, dcsr_single_step_running_f}), + .dout({halt_taken_f, take_halt_f, lsu_idle_any_f, ifu_miss_state_idle_f, dbg_tlu_halted_f, dec_tlu_resume_ack, dec_dbg_cmd_done, dbg_halt_req_f, dbg_resume_req_f, trigger_hit_dmode_wb, dcsr_single_step_done_f, dbg_halt_req_d1, update_hit_bit_wb[3:0], dec_tlu_wr_pause_wb_f, dec_pause_state_f, request_debug_mode_wb, request_debug_mode_done_f, dcsr_single_step_running_f, dcsr_single_step_running_ff})); @@ -483,7 +483,7 @@ module dec_tlu_ctl // detect end of pause counter and rfpc assign pause_expired_e4 = ~dec_pause_state & dec_pause_state_f & ~(ext_int_ready | ce_int_ready | timer_int_ready | nmi_int_detected) & ~interrupt_valid_wb & ~dbg_halt_req_f & ~pmu_fw_halt_req_f & ~halt_taken_f; - + // stall dma fifo if a fence is pending, decode is waiting for lsu to idle before decoding the fence inst. assign dec_tlu_stall_dma = dec_fence_pending; assign dec_tlu_flush_leak_one_wb = dec_tlu_flush_lower_wb & dcsr[`DCSR_STEP] & dec_tlu_resume_ack; @@ -492,7 +492,7 @@ module dec_tlu_ctl // If DM attempts to access an illegal CSR, send cmd_fail back assign dec_dbg_cmd_fail = illegal_raw_wb & dec_dbg_cmd_done; - + //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- // Triggers @@ -517,9 +517,9 @@ module dec_tlu_ctl assign trigger_store[3:0] = {mtdata1_t3[`MTDATA1_ST], mtdata1_t2[`MTDATA1_ST], mtdata1_t1[`MTDATA1_ST], mtdata1_t0[`MTDATA1_ST]}; // MSTATUS[MIE] needs to be on to take triggers unless the action is trigger to debug mode. - assign trigger_enabled[3:0] = {(mtdata1_t3[`MTDATA1_ACTION] | mstatus[`MSTATUS_MIE]) & mtdata1_t3[`MTDATA1_M_ENABLED], - (mtdata1_t2[`MTDATA1_ACTION] | mstatus[`MSTATUS_MIE]) & mtdata1_t2[`MTDATA1_M_ENABLED], - (mtdata1_t1[`MTDATA1_ACTION] | mstatus[`MSTATUS_MIE]) & mtdata1_t1[`MTDATA1_M_ENABLED], + assign trigger_enabled[3:0] = {(mtdata1_t3[`MTDATA1_ACTION] | mstatus[`MSTATUS_MIE]) & mtdata1_t3[`MTDATA1_M_ENABLED], + (mtdata1_t2[`MTDATA1_ACTION] | mstatus[`MSTATUS_MIE]) & mtdata1_t2[`MTDATA1_M_ENABLED], + (mtdata1_t1[`MTDATA1_ACTION] | mstatus[`MSTATUS_MIE]) & mtdata1_t1[`MTDATA1_M_ENABLED], (mtdata1_t0[`MTDATA1_ACTION] | mstatus[`MSTATUS_MIE]) & mtdata1_t0[`MTDATA1_M_ENABLED]}; // iside exceptions are always in i0 @@ -531,7 +531,7 @@ module dec_tlu_ctl // lsu excs have to line up with their respective triggers since the lsu op can be in either i0 or i1 but not both assign i0_lsu_trigger_has_pri_e4[3:0] = ~(trigger_store[3:0] & trigger_data[3:0] & {4{lsu_i0_exc_dc4_raw}}); assign i1_lsu_trigger_has_pri_e4[3:0] = ~(trigger_store[3:0] & trigger_data[3:0] & {4{lsu_i1_exc_dc4_raw}}); - + assign i0trigger_qual_e4[3:0] = dec_tlu_packet_e4.i0trigger[3:0] & i0_iside_trigger_has_pri_e4[3:0] & i0_lsu_trigger_has_pri_e4[3:0] & trigger_enabled[3:0]; assign i1trigger_qual_e4[3:0] = dec_tlu_packet_e4.i1trigger[3:0] & i1_iside_trigger_has_pri_e4[3:0] & i1_lsu_trigger_has_pri_e4[3:0] & trigger_enabled[3:0]; @@ -545,12 +545,12 @@ module dec_tlu_ctl assign i0_trigger_chain_masked_e4[3:0] = {i0_trigger_e4[3] & (~trigger_chain[2] | i0_trigger_e4[2]), i0_trigger_e4[2] & (~trigger_chain[2] | i0_trigger_e4[3]), i0_trigger_e4[1] & (~trigger_chain[0] | i0_trigger_e4[0]), - i0_trigger_e4[0] & (~trigger_chain[0] | i0_trigger_e4[1])}; + i0_trigger_e4[0] & (~trigger_chain[0] | i0_trigger_e4[1])}; assign i1_trigger_chain_masked_e4[3:0] = {i1_trigger_e4[3] & (~trigger_chain[2] | i1_trigger_e4[2]), i1_trigger_e4[2] & (~trigger_chain[2] | i1_trigger_e4[3]), i1_trigger_e4[1] & (~trigger_chain[0] | i1_trigger_e4[0]), - i1_trigger_e4[0] & (~trigger_chain[0] | i1_trigger_e4[1])}; + i1_trigger_e4[0] & (~trigger_chain[0] | i1_trigger_e4[1])}; // This is the highest priority by this point. assign i0_trigger_hit_e4 = |i0_trigger_chain_masked_e4[3:0]; @@ -558,13 +558,13 @@ module dec_tlu_ctl // Actions include breakpoint, or dmode. Dmode is only possible if the DMODE bit is set. // Otherwise, take a breakpoint. - assign trigger_action[3:0] = {mtdata1_t3[`MTDATA1_ACTION] & mtdata1_t3[`MTDATA1_DMODE], - mtdata1_t2[`MTDATA1_ACTION] & mtdata1_t2[`MTDATA1_DMODE], - mtdata1_t1[`MTDATA1_ACTION] & mtdata1_t1[`MTDATA1_DMODE], + assign trigger_action[3:0] = {mtdata1_t3[`MTDATA1_ACTION] & mtdata1_t3[`MTDATA1_DMODE], + mtdata1_t2[`MTDATA1_ACTION] & mtdata1_t2[`MTDATA1_DMODE], + mtdata1_t1[`MTDATA1_ACTION] & mtdata1_t1[`MTDATA1_DMODE], mtdata1_t0[`MTDATA1_ACTION] & mtdata1_t0[`MTDATA1_DMODE]}; // this is needed to set the HIT bit in the triggers - assign update_hit_bit_e4[3:0] = ({4{i0_trigger_hit_e4 }} & i0_trigger_chain_masked_e4[3:0]) | + assign update_hit_bit_e4[3:0] = ({4{i0_trigger_hit_e4 }} & i0_trigger_chain_masked_e4[3:0]) | ({4{i1_trigger_hit_e4 & ~i0_trigger_hit_e4}} & i1_trigger_chain_masked_e4[3:0]); // action, 1 means dmode. Simultaneous triggers with at least 1 set for dmode force entire action to dmode. @@ -573,14 +573,14 @@ module dec_tlu_ctl assign trigger_hit_e4 = i0_trigger_hit_e4 | i1_trigger_hit_e4; assign trigger_hit_dmode_e4 = (i0_trigger_hit_e4 & i0_trigger_action_e4) | (i1_trigger_hit_e4 & ~i0_trigger_hit_e4 & i1_trigger_action_e4); - + assign mepc_trigger_hit_sel_pc_e4 = trigger_hit_e4 & ~trigger_hit_dmode_e4; - - -// + + +// // Debug end //-------------------------------------------------------------------------------- - + //---------------------------------------------------------------------- // // Commit @@ -590,7 +590,7 @@ module dec_tlu_ctl //-------------------------------------------------------------------------------- - // External halt (not debug halt) + // External halt (not debug halt) // - Fully interlocked handshake // i_cpu_halt_req ____|--------------|_______________ // core_empty ---------------|___________ @@ -604,17 +604,17 @@ module dec_tlu_ctl // debug mode has priority, ignore PMU/FW halt/run while in debug mode assign i_cpu_halt_req_sync_qual = i_cpu_halt_req_sync & ~dec_tlu_debug_mode; assign i_cpu_run_req_sync_qual = i_cpu_run_req_sync & ~dec_tlu_debug_mode & pmu_fw_tlu_halted_f; - - rvdff #(8) exthaltff (.*, .clk(free_clk), .din({i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, cpu_halt_status, + + rvdff #(8) exthaltff (.*, .clk(free_clk), .din({i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, cpu_halt_status, cpu_halt_ack, cpu_run_ack, internal_pmu_fw_halt_mode, - pmu_fw_halt_req_ns, pmu_fw_tlu_halted}), - .dout({i_cpu_halt_req_d1, i_cpu_run_req_d1_raw, o_cpu_halt_status, + pmu_fw_halt_req_ns, pmu_fw_tlu_halted}), + .dout({i_cpu_halt_req_d1, i_cpu_run_req_d1_raw, o_cpu_halt_status, o_cpu_halt_ack, o_cpu_run_ack, internal_pmu_fw_halt_mode_f, pmu_fw_halt_req_f, pmu_fw_tlu_halted_f})); // only happens if we aren't in dgb_halt assign ext_halt_pulse = i_cpu_halt_req_sync_qual & ~i_cpu_halt_req_d1; - + assign enter_pmu_fw_halt_req = ext_halt_pulse | fw_halt_req; assign pmu_fw_halt_req_ns = (enter_pmu_fw_halt_req | (pmu_fw_halt_req_f & ~pmu_fw_tlu_halted)) & ~dbg_halt_req_f; @@ -630,16 +630,16 @@ module dec_tlu_ctl assign debug_mode_status = internal_dbg_halt_mode_f; assign o_debug_mode_status = debug_mode_status; -`ifdef ASSERT_ON +`ifdef ASSERT_ON assert_commit_while_halted: assert #0 (~((tlu_i0_commit_cmt | tlu_i1_commit_cmt) & o_cpu_halt_status)) else $display("ERROR: Commiting while cpu_halt_status asserted!"); `endif - + // high priority interrupts can wakeup from external halt, so can unmasked timer interrupts assign i_cpu_run_req_d1 = i_cpu_run_req_d1_raw | ((nmi_int_detected | timer_int_ready | (mhwakeup & mhwakeup_ready)) & o_cpu_halt_status); //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- - + // LSU exceptions (LSU responsible for prioritizing simultaneous cases) lsu_error_pkt_t lsu_error_pkt_dc4; @@ -648,7 +648,7 @@ module dec_tlu_ctl logic lsu_single_ecc_error_wb_ns; assign lsu_single_ecc_error_wb_ns = lsu_error_pkt_dc4.single_ecc_error;// & ((~lsu_error_pkt_dc4.inst_pipe & tlu_i0_commit_cmt) | (lsu_error_pkt_dc4.inst_pipe & tlu_i1_commit_cmt)); rvdff #(2) lsu_dccm_errorff (.*, .clk(free_clk), .din({mdseac_locked_ns, lsu_single_ecc_error_wb_ns}), .dout({mdseac_locked_f, lsu_single_ecc_error_wb})); - + logic [31:0] lsu_error_pkt_addr_dc4, lsu_error_pkt_addr_wb; assign lsu_error_pkt_addr_dc4[31:0] = lsu_error_pkt_dc4.addr[31:0]; rvdff #(34) lsu_error_wbff (.*, .clk(lsu_e4_e5_clk), .din({lsu_error_pkt_addr_dc4[31:0], lsu_exc_valid_e4, lsu_i0_exc_dc4}), .dout({lsu_error_pkt_addr_wb[31:0], lsu_exc_valid_wb, lsu_i0_exc_wb})); @@ -656,13 +656,13 @@ module dec_tlu_ctl // lsu exception is valid unless it's in pipe1 and there was a rfpc_i0_e4, brmp, or an iside exception in pipe0. assign lsu_exc_valid_e4_raw = lsu_error_pkt_dc4.exc_valid & ~(lsu_error_pkt_dc4.inst_pipe & (rfpc_i0_e4 | i0_exception_valid_e4 | exu_i0_br_mp_e4)) & ~dec_tlu_flush_lower_wb; - + assign lsu_i0_exc_dc4_raw = lsu_error_pkt_dc4.exc_valid & ~lsu_error_pkt_dc4.inst_pipe; assign lsu_i1_exc_dc4_raw = lsu_error_pkt_dc4.exc_valid & lsu_error_pkt_dc4.inst_pipe; assign lsu_i0_exc_dc4 = lsu_i0_exc_dc4_raw & lsu_exc_valid_e4_raw & ~i0_trigger_hit_e4; assign lsu_i1_exc_dc4 = lsu_i1_exc_dc4_raw & lsu_exc_valid_e4_raw & ~trigger_hit_e4; assign lsu_exc_valid_e4 = lsu_i0_exc_dc4 | lsu_i1_exc_dc4; - + assign lsu_exc_ma_dc4 = (lsu_i0_exc_dc4 | lsu_i1_exc_dc4) & ~lsu_error_pkt_dc4.exc_type; assign lsu_exc_acc_dc4 = (lsu_i0_exc_dc4 | lsu_i1_exc_dc4) & lsu_error_pkt_dc4.exc_type; assign lsu_exc_st_dc4 = (lsu_i0_exc_dc4 | lsu_i1_exc_dc4) & lsu_error_pkt_dc4.inst_type; @@ -679,22 +679,22 @@ module dec_tlu_ctl // Final commit valids - assign tlu_i0_commit_cmt = dec_tlu_i0_valid_e4 & - ~rfpc_i0_e4 & - ~lsu_i0_exc_dc4 & - ~inst_acc_e4 & - ~dec_tlu_dbg_halted & + assign tlu_i0_commit_cmt = dec_tlu_i0_valid_e4 & + ~rfpc_i0_e4 & + ~lsu_i0_exc_dc4 & + ~inst_acc_e4 & + ~dec_tlu_dbg_halted & ~request_debug_mode_wb & ~i0_trigger_hit_e4; - - assign tlu_i1_commit_cmt = dec_tlu_i1_valid_e4 & - ~rfpc_i0_e4 & ~rfpc_i1_e4 & - ~exu_i0_br_mp_e4 & - ~lsu_i0_exc_dc4 & ~lsu_i1_exc_dc4 & + + assign tlu_i1_commit_cmt = dec_tlu_i1_valid_e4 & + ~rfpc_i0_e4 & ~rfpc_i1_e4 & + ~exu_i0_br_mp_e4 & + ~lsu_i0_exc_dc4 & ~lsu_i1_exc_dc4 & ~inst_acc_e4 & ~request_debug_mode_wb & ~trigger_hit_e4; - + // unified place to manage the killing of arch state writebacks assign tlu_i0_kill_writeb_e4 = rfpc_i0_e4 | lsu_i0_exc_dc4 | inst_acc_e4 | (illegal_e4 & dec_tlu_dbg_halted) | i0_trigger_hit_e4 ; assign tlu_i1_kill_writeb_e4 = rfpc_i0_e4 | rfpc_i1_e4 | lsu_exc_valid_e4 | exu_i0_br_mp_e4 | inst_acc_e4 | (illegal_e4 & dec_tlu_dbg_halted) | trigger_hit_e4; @@ -703,7 +703,7 @@ module dec_tlu_ctl // ic errors only in pipe0 assign rfpc_i0_e4 = dec_tlu_i0_valid_e4 & ~tlu_flush_lower_wb & (exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4 | lsu_i0_rfpc_dc4) & ~i0_trigger_hit_e4; assign rfpc_i1_e4 = dec_tlu_i1_valid_e4 & ~tlu_flush_lower_wb & ~i0_exception_valid_e4 & ~exu_i0_br_mp_e4 & ~lsu_i0_exc_dc4 & - ~(exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4 | lsu_i0_rfpc_dc4) & + ~(exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4 | lsu_i0_rfpc_dc4) & (exu_i1_br_error_e4 | exu_i1_br_start_error_e4 | lsu_i1_rfpc_dc4) & ~trigger_hit_e4; @@ -715,18 +715,18 @@ module dec_tlu_ctl assign dec_tlu_br1_error_e4 = exu_i1_br_error_e4 & dec_tlu_i1_valid_e4 & ~tlu_flush_lower_wb & ~exu_i0_br_mp_e4; assign dec_tlu_br1_start_error_e4 = exu_i1_br_start_error_e4 & dec_tlu_i1_valid_e4 & ~tlu_flush_lower_wb & ~exu_i0_br_mp_e4; assign dec_tlu_br1_v_e4 = exu_i1_br_valid_e4 & ~tlu_flush_lower_wb & dec_tlu_i1_valid_e4 & ~exu_i0_br_mp_e4 & ~exu_i1_br_mp_e4; - + `ifdef RV_BTB_48 - rvdff #(20) + rvdff #(20) `else - rvdff #(18) + rvdff #(18) `endif bp_wb_ff (.*, .clk(e4e5_clk), - .din({exu_i0_br_hist_e4[1:0], + .din({exu_i0_br_hist_e4[1:0], dec_tlu_br0_error_e4, dec_tlu_br0_start_error_e4, dec_tlu_br0_v_e4, - exu_i1_br_hist_e4[1:0], + exu_i1_br_hist_e4[1:0], dec_tlu_br1_error_e4, dec_tlu_br1_start_error_e4, dec_tlu_br1_v_e4, @@ -736,14 +736,14 @@ module dec_tlu_ctl exu_i1_br_way_e4, exu_i0_br_middle_e4, exu_i1_br_middle_e4 - }), - .dout({dec_tlu_br0_wb_pkt.hist[1:0], - dec_tlu_br0_wb_pkt.br_error, - dec_tlu_br0_wb_pkt.br_start_error, + }), + .dout({dec_tlu_br0_wb_pkt.hist[1:0], + dec_tlu_br0_wb_pkt.br_error, + dec_tlu_br0_wb_pkt.br_start_error, dec_tlu_br0_wb_pkt.valid, - dec_tlu_br1_wb_pkt.hist[1:0], - dec_tlu_br1_wb_pkt.br_error, - dec_tlu_br1_wb_pkt.br_start_error, + dec_tlu_br1_wb_pkt.hist[1:0], + dec_tlu_br1_wb_pkt.br_error, + dec_tlu_br1_wb_pkt.br_start_error, dec_tlu_br1_wb_pkt.valid, dec_tlu_br0_wb_pkt.bank[1:0], dec_tlu_br1_wb_pkt.bank[1:0], @@ -753,18 +753,18 @@ module dec_tlu_ctl dec_tlu_br1_wb_pkt.middle })); - rvdff #(`RV_BHT_GHR_SIZE*2) bp_wb_ghrff (.*, .clk(e4e5_clk), + rvdff #(`RV_BHT_GHR_SIZE*2) bp_wb_ghrff (.*, .clk(e4e5_clk), .din({exu_i0_br_fghr_e4[`RV_BHT_GHR_RANGE], exu_i1_br_fghr_e4[`RV_BHT_GHR_RANGE] - }), + }), .dout({dec_tlu_br0_wb_pkt.fghr[`RV_BHT_GHR_RANGE], dec_tlu_br1_wb_pkt.fghr[`RV_BHT_GHR_RANGE] })); - rvdff #(2*$bits(dec_tlu_br0_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO])) + rvdff #(2*$bits(dec_tlu_br0_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO])) bp_wb_index_ff (.*, .clk(e4e5_clk), .din({dec_tlu_br0_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO], - dec_tlu_br1_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]}), + dec_tlu_br1_addr_e4[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]}), .dout({dec_tlu_br0_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO], dec_tlu_br1_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]})); @@ -780,15 +780,15 @@ module dec_tlu_ctl assign inst_acc_e4_raw = dec_tlu_packet_e4.icaf & dec_tlu_i0_valid_e4; assign inst_acc_e4 = inst_acc_e4_raw & ~rfpc_i0_e4 & ~i0_trigger_hit_e4; assign inst_acc_second_e4 = dec_tlu_packet_e4.icaf_f1; - + assign ebreak_to_debug_mode_e4 = (dec_tlu_packet_e4.pmu_i0_itype == EBREAK) & dec_tlu_i0_valid_e4 & ~i0_trigger_hit_e4 & dcsr[`DCSR_EBREAKM]; assign illegal_e4_qual = illegal_e4 & ~dec_tlu_dbg_halted; - rvdff #(10) exctype_wb_ff (.*, .clk(e4e5_clk), - .din({ic_perr_e4, iccm_sbecc_e4, ebreak_e4, ebreak_to_debug_mode_e4, illegal_e4, - illegal_e4_qual, inst_acc_e4, inst_acc_second_e4, fence_i_e4, mret_e4}), - .dout({ic_perr_wb, iccm_sbecc_wb, ebreak_wb, ebreak_to_debug_mode_wb, illegal_raw_wb, + rvdff #(10) exctype_wb_ff (.*, .clk(e4e5_clk), + .din({ic_perr_e4, iccm_sbecc_e4, ebreak_e4, ebreak_to_debug_mode_e4, illegal_e4, + illegal_e4_qual, inst_acc_e4, inst_acc_second_e4, fence_i_e4, mret_e4}), + .dout({ic_perr_wb, iccm_sbecc_wb, ebreak_wb, ebreak_to_debug_mode_wb, illegal_raw_wb, illegal_wb, inst_acc_wb, inst_acc_second_wb, fence_i_wb, mret_wb})); assign dec_tlu_fence_i_wb = fence_i_wb; @@ -805,12 +805,12 @@ module dec_tlu_ctl assign i0_exception_valid_e4 = (ebreak_e4 | ecall_e4 | illegal_e4 | inst_acc_e4) & ~rfpc_i0_e4 & ~dec_tlu_dbg_halted; // Cause: - // + // // 0x2 : illegal // 0x3 : breakpoint // 0xb : Environment call M-mode - + assign exc_cause_e4[4:0] = ( ({5{take_ext_int}} & 5'h0b) | ({5{take_timer_int}} & 5'h07) | ({5{take_ce_int}} & 5'h1e) | @@ -827,14 +827,14 @@ module dec_tlu_ctl // // Interrupts // - // Priv spec 1.10, 3.1.14 + // Priv spec 1.10, 3.1.14 // "Multiple simultaneous interrupts and traps at the same privilege level are handled in the following // decreasing priority order: external interrupts, software interrupts, timer interrupts, then finally any // synchronous traps." // - // For above purposes, exceptions that are committed have already happened and will cause an int at E4 to wait a cycle + // For above purposes, exceptions that are committed have already happened and will cause an int at E4 to wait a cycle // or more if MSTATUS[MIE] is cleared. - // + // // -in priority order, highest to lowest // -single cycle window where a csr write to MIE/MSTATUS is at E4 when the other conditions for externals are met. // Hold off externals for a cycle to make sure we are consistent with what was just written @@ -846,7 +846,7 @@ module dec_tlu_ctl // mispredicts assign i0_mp_e4 = exu_i0_flush_lower_e4 & ~i0_trigger_hit_e4; assign i1_mp_e4 = exu_i1_flush_lower_e4 & ~trigger_hit_e4; - + assign internal_dbg_halt_timers = internal_dbg_halt_mode_f & ~dcsr_single_step_running; // Prioritize externals @@ -860,16 +860,16 @@ module dec_tlu_ctl mret_wb | // mret (need time for MIE to update) mret_e4 // mret in progress, for cases were ISR enables ints before mret ); - + assign take_ext_int = ext_int_ready & ~block_interrupts; assign take_ce_int = ce_int_ready & ~ext_int_ready & ~block_interrupts; assign take_timer_int = timer_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts; - + assign take_reset = reset_delayed; assign take_nmi = nmi_int_detected & ~internal_pmu_fw_halt_mode & (~internal_dbg_halt_mode | (dcsr_single_step_running_f & dcsr[`DCSR_STEPIE] & ~dec_tlu_i0_valid_e4)) & ~synchronous_flush_e4 & ~mret_e4 & ~take_reset & ~ebreak_to_debug_mode_e4; assign interrupt_valid = take_ext_int | take_timer_int | take_nmi | take_ce_int; - + // Compute interrupt path: // If vectored async is set in mtvec, flush path for interrupts is MTVEC + (4 * CAUSE); @@ -880,7 +880,7 @@ module dec_tlu_ctl assign sel_npc_e4 = fence_i_e4 | (i_cpu_run_req_d1 & ~interrupt_valid); assign sel_npc_wb = (i_cpu_run_req_d1 & pmu_fw_tlu_halted_f) | pause_expired_e4; - + assign synchronous_flush_e4 = i0_exception_valid_e4 | // exception i0_mp_e4 | i1_mp_e4 | // mispredict rfpc_i0_e4 | rfpc_i1_e4 | // rfpc @@ -894,39 +894,39 @@ module dec_tlu_ctl assign tlu_flush_lower_e4 = interrupt_valid | mret_e4 | synchronous_flush_e4 | take_halt | take_reset; assign tlu_flush_path_e4[31:1] = take_reset ? rst_vec[31:1] : - - ( ({31{~take_nmi & i0_mp_e4}} & exu_i0_flush_path_e4[31:1]) | + + ( ({31{~take_nmi & i0_mp_e4}} & exu_i0_flush_path_e4[31:1]) | ({31{~take_nmi & ~i0_mp_e4 & i1_mp_e4 & ~rfpc_i0_e4 & ~lsu_i0_exc_dc4}} & exu_i1_flush_path_e4[31:1]) | - ({31{~take_nmi & sel_npc_e4}} & npc_e4[31:1]) | - ({31{~take_nmi & rfpc_i0_e4}} & dec_tlu_i0_pc_e4[31:1]) | - ({31{~take_nmi & rfpc_i1_e4}} & dec_tlu_i1_pc_e4[31:1]) | - ({31{interrupt_valid}} & interrupt_path[31:1]) | + ({31{~take_nmi & sel_npc_e4}} & npc_e4[31:1]) | + ({31{~take_nmi & rfpc_i0_e4}} & dec_tlu_i0_pc_e4[31:1]) | + ({31{~take_nmi & rfpc_i1_e4}} & dec_tlu_i1_pc_e4[31:1]) | + ({31{interrupt_valid}} & interrupt_path[31:1]) | ({31{(i0_exception_valid_e4 | lsu_exc_valid_e4 | (trigger_hit_e4 & ~trigger_hit_dmode_e4)) & ~interrupt_valid}} & {mtvec[30:1],1'b0}) | ({31{~take_nmi & mret_e4 & ~wr_mepc_wb}} & mepc[31:1]) | ({31{~take_nmi & dbg_resume_req_f}} & dpc[31:1]) | ({31{~take_nmi & sel_npc_wb}} & npc_wb[31:1]) | ({31{~take_nmi & mret_e4 & wr_mepc_wb}} & dec_csr_wrdata_wb[31:1]) ); - rvdff #(31) flush_lower_ff (.*, .clk(e4e5_int_clk), - .din({tlu_flush_path_e4[31:1]}), + rvdff #(31) flush_lower_ff (.*, .clk(e4e5_int_clk), + .din({tlu_flush_path_e4[31:1]}), .dout({tlu_flush_path_wb[31:1]})); assign dec_tlu_flush_lower_wb = tlu_flush_lower_wb; assign dec_tlu_flush_path_wb[31:1] = tlu_flush_path_wb[31:1]; - + // this is used to capture mepc, etc. assign exc_or_int_valid = lsu_exc_valid_e4 | i0_exception_valid_e4 | interrupt_valid | (trigger_hit_e4 & ~trigger_hit_dmode_e4); assign lsu_block_interrupts_dc3 = lsu_freeze_external_ints_dc3 & ~dec_tlu_flush_lower_wb; - - rvdff #(14) excinfo_wb_ff (.*, .clk(e4e5_int_clk), - .din({interrupt_valid, i0_exception_valid_e4, exc_or_int_valid, - exc_cause_e4[4:0], tlu_i0_commit_cmt, tlu_i1_commit_cmt, + + rvdff #(14) excinfo_wb_ff (.*, .clk(e4e5_int_clk), + .din({interrupt_valid, i0_exception_valid_e4, exc_or_int_valid, + exc_cause_e4[4:0], tlu_i0_commit_cmt, tlu_i1_commit_cmt, mepc_trigger_hit_sel_pc_e4, trigger_hit_e4, - take_nmi, pause_expired_e4 }), - .dout({interrupt_valid_wb, i0_exception_valid_wb, exc_or_int_valid_wb, - exc_cause_wb[4:0], i0_valid_wb, i1_valid_wb, + take_nmi, pause_expired_e4 }), + .dout({interrupt_valid_wb, i0_exception_valid_wb, exc_or_int_valid_wb, + exc_cause_wb[4:0], i0_valid_wb, i1_valid_wb, mepc_trigger_hit_sel_pc_wb, trigger_hit_wb, take_nmi_wb, pause_expired_wb})); @@ -951,7 +951,7 @@ module dec_tlu_ctl `define MIMPID 12'hf13 `define MHARTID 12'hf14 - + // ---------------------------------------------------------------------- // MSTATUS (RW) // [12:11] MPP : Prior priv level, always 2'b11, not flopped @@ -981,14 +981,14 @@ module dec_tlu_ctl // [1] - Reserved, not implemented, reads zero // [0] MODE : 0 = Direct, 1 = Asyncs are vectored to BASE + (4 * CAUSE) `define MTVEC 12'h305 - + assign wr_mtvec_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTVEC); - assign mtvec_ns[30:0] = {dec_csr_wrdata_wb[31:2], dec_csr_wrdata_wb[0]} ; + assign mtvec_ns[30:0] = {dec_csr_wrdata_wb[31:2], dec_csr_wrdata_wb[0]} ; rvdffe #(31) mtvec_ff (.*, .en(wr_mtvec_wb), .din(mtvec_ns[30:0]), .dout(mtvec[30:0])); // ---------------------------------------------------------------------- // MIP (RW) - // + // // [30] MCEIP : (RO) M-Mode Correctable Error interrupt pending // [11] MEIP : (RO) M-Mode external interrupt pending // [7] MTIP : (RO) M-Mode timer interrupt pending @@ -997,7 +997,7 @@ module dec_tlu_ctl assign ce_int = (mdccme_ce_req | miccme_ce_req | mice_ce_req); - assign mip_ns[3:0] = {ce_int, mexintpend, timer_int_sync, mip[0]}; + assign mip_ns[3:0] = {ce_int, mexintpend, timer_int_sync, mip[0]}; rvdff #(4) mip_ff (.*, .clk(free_clk), .din(mip_ns[3:0]), .dout(mip[3:0])); // ---------------------------------------------------------------------- @@ -1007,27 +1007,27 @@ module dec_tlu_ctl // [7] MTIE : (RW) M-Mode timer interrupt enable // [3] MSIE : (RW) M-Mode software interrupt enable `define MIE 12'h304 - + assign wr_mie_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MIE); - assign mie_ns[3:0] = wr_mie_wb ? {dec_csr_wrdata_wb[30], dec_csr_wrdata_wb[11], dec_csr_wrdata_wb[7], dec_csr_wrdata_wb[3]} : mie[3:0]; + assign mie_ns[3:0] = wr_mie_wb ? {dec_csr_wrdata_wb[30], dec_csr_wrdata_wb[11], dec_csr_wrdata_wb[7], dec_csr_wrdata_wb[3]} : mie[3:0]; rvdff #(4) mie_ff (.*, .clk(csr_wr_clk), .din(mie_ns[3:0]), .dout(mie[3:0])); // ---------------------------------------------------------------------- // MCYCLEL (RW) // [31:0] : Lower Cycle count - + `define MCYCLEL 12'hb00 assign wr_mcyclel_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MCYCLEL); logic mcyclel_cout_in; - + assign mcyclel_cout_in = ~(kill_ebreak_count_wb | (dec_tlu_dbg_halted & dcsr[`DCSR_STOPC]) | dec_tlu_pmu_fw_halted); - - assign {mcyclel_cout, mcyclel_inc[31:0]} = mcyclel[31:0] + {31'b0, mcyclel_cout_in}; - assign mcyclel_ns[31:0] = wr_mcyclel_wb ? dec_csr_wrdata_wb[31:0] : mcyclel_inc[31:0]; + + assign {mcyclel_cout, mcyclel_inc[31:0]} = mcyclel[31:0] + {31'b0, mcyclel_cout_in}; + assign mcyclel_ns[31:0] = wr_mcyclel_wb ? dec_csr_wrdata_wb[31:0] : mcyclel_inc[31:0]; rvdffe #(32) mcyclel_ff (.*, .en(wr_mcyclel_wb | mcyclel_cout_in), .din(mcyclel_ns[31:0]), .dout(mcyclel[31:0])); rvdff #(1) mcyclef_cout_ff (.*, .clk(free_clk), .din(mcyclel_cout & ~wr_mcycleh_wb), .dout(mcyclel_cout_f)); @@ -1037,14 +1037,14 @@ module dec_tlu_ctl // Chained with mcyclel. Note: mcyclel overflow due to a mcycleh write gets ignored. `define MCYCLEH 12'hb80 - + assign wr_mcycleh_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MCYCLEH); - assign {mcycleh_cout_nc, mcycleh_inc[31:0]} = mcycleh[31:0] + {31'b0, mcyclel_cout_f}; - assign mcycleh_ns[31:0] = wr_mcycleh_wb ? dec_csr_wrdata_wb[31:0] : mcycleh_inc[31:0]; + assign {mcycleh_cout_nc, mcycleh_inc[31:0]} = mcycleh[31:0] + {31'b0, mcyclel_cout_f}; + assign mcycleh_ns[31:0] = wr_mcycleh_wb ? dec_csr_wrdata_wb[31:0] : mcycleh_inc[31:0]; rvdffe #(32) mcycleh_ff (.*, .en(wr_mcycleh_wb | mcyclel_cout_f), .din(mcycleh_ns[31:0]), .dout(mcycleh[31:0])); - + // ---------------------------------------------------------------------- // MINSTRETL (RW) // [31:0] : Lower Instruction retired count @@ -1057,14 +1057,14 @@ module dec_tlu_ctl `define MINSTRETL 12'hb02 assign kill_ebreak_count_wb = ebreak_to_debug_mode_wb & dcsr[`DCSR_STOPC]; - + assign wr_minstretl_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MINSTRETL); - assign {minstretl_cout, minstretl_inc[31:0]} = minstretl[31:0] + {31'b0,i0_valid_wb} + {31'b0,i1_valid_wb}; + assign {minstretl_cout, minstretl_inc[31:0]} = minstretl[31:0] + {31'b0,i0_valid_wb} + {31'b0,i1_valid_wb}; assign minstret_enable = (i0_valid_wb & ~(dec_tlu_dbg_halted & dcsr[`DCSR_STOPC]) & ~kill_ebreak_count_wb) | i1_valid_wb | wr_minstretl_wb; - - assign minstretl_ns[31:0] = wr_minstretl_wb ? dec_csr_wrdata_wb[31:0] : minstretl_inc[31:0]; + + assign minstretl_ns[31:0] = wr_minstretl_wb ? dec_csr_wrdata_wb[31:0] : minstretl_inc[31:0]; rvdffe #(32) minstretl_ff (.*, .en(minstret_enable), .din(minstretl_ns[31:0]), .dout(minstretl[31:0])); logic minstret_enable_f; rvdff #(2) minstretf_cout_ff (.*, .clk(free_clk), .din({minstret_enable, minstretl_cout & ~wr_minstreth_wb}), .dout({minstret_enable_f, minstretl_cout_f})); @@ -1077,20 +1077,20 @@ module dec_tlu_ctl // See JIRA RISCV-105 for details. `define MINSTRETH 12'hb82 - + assign wr_minstreth_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MINSTRETH); - assign {minstreth_cout_nc, minstreth_inc[31:0]} = minstreth[31:0] + {31'b0, minstretl_cout_f}; - assign minstreth_ns[31:0] = wr_minstreth_wb ? dec_csr_wrdata_wb[31:0] : minstreth_inc[31:0]; + assign {minstreth_cout_nc, minstreth_inc[31:0]} = minstreth[31:0] + {31'b0, minstretl_cout_f}; + assign minstreth_ns[31:0] = wr_minstreth_wb ? dec_csr_wrdata_wb[31:0] : minstreth_inc[31:0]; rvdffe #(32) minstreth_ff (.*, .en(minstret_enable_f | wr_minstreth_wb), .din(minstreth_ns[31:0]), .dout(minstreth[31:0])); - + assign minstreth_read[31:0] = minstreth_inc[31:0]; // ---------------------------------------------------------------------- // MSCRATCH (RW) // [31:0] : Scratch register `define MSCRATCH 12'h340 - + assign wr_mscratch_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MSCRATCH); rvdffe #(32) mscratch_ff (.*, .en(wr_mscratch_wb), .din(dec_csr_wrdata_wb[31:0]), .dout(mscratch[31:0])); @@ -1102,51 +1102,51 @@ module dec_tlu_ctl // NPC logic sel_exu_npc_e4, sel_flush_npc_e4, sel_hold_np_e4; - + assign sel_exu_npc_e4 = ~dec_tlu_dbg_halted & ~tlu_flush_lower_wb & (dec_tlu_i0_valid_e4 | dec_tlu_i1_valid_e4); assign sel_flush_npc_e4 = ~dec_tlu_dbg_halted & tlu_flush_lower_wb & ~dec_tlu_flush_noredir_wb; assign sel_hold_np_e4 = ~sel_exu_npc_e4 & ~sel_flush_npc_e4; - + assign npc_e4[31:1] = ( ({31{sel_exu_npc_e4}} & exu_npc_e4[31:1]) | ({31{(sel_flush_npc_e4)}} & tlu_flush_path_wb[31:1]) | ({31{(sel_hold_np_e4)}} & npc_wb[31:1]) ); rvdffe #(31) npwbc_ff (.*, .en(sel_exu_npc_e4 | sel_flush_npc_e4), .din(npc_e4[31:1]), .dout(npc_wb[31:1])); - + // PC has to be captured for exceptions and interrupts. For MRET, we could execute it and then take an // interrupt before the next instruction. logic pc0_valid_e4, pc1_valid_e4; assign pc0_valid_e4 = ~dec_tlu_dbg_halted & dec_tlu_i0_valid_e4; assign pc1_valid_e4 = ~dec_tlu_dbg_halted & dec_tlu_i0_valid_e4 & dec_tlu_i1_valid_e4 & ~lsu_i0_exc_dc4 & ~rfpc_i0_e4 & ~inst_acc_e4 & ~i0_trigger_hit_e4; - + assign pc_e4[31:1] = ( ({31{ pc0_valid_e4 & ~pc1_valid_e4}} & dec_tlu_i0_pc_e4[31:1]) | ({31{ pc1_valid_e4}} & dec_tlu_i1_pc_e4[31:1]) | ({31{~pc0_valid_e4 & ~pc1_valid_e4}} & pc_wb[31:1])); rvdffe #(31) pwbc_ff (.*, .en(pc0_valid_e4 | pc1_valid_e4), .din(pc_e4[31:1]), .dout(pc_wb[31:1])); - + assign wr_mepc_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MEPC); assign mepc_ns[31:1] = ( ({31{i0_exception_valid_wb | lsu_exc_valid_wb | mepc_trigger_hit_sel_pc_wb}} & pc_wb[31:1]) | ({31{interrupt_valid_wb}} & npc_wb[31:1]) | ({31{wr_mepc_wb & ~exc_or_int_valid_wb}} & dec_csr_wrdata_wb[31:1]) | - ({31{~wr_mepc_wb & ~exc_or_int_valid_wb}} & mepc[31:1]) ); + ({31{~wr_mepc_wb & ~exc_or_int_valid_wb}} & mepc[31:1]) ); rvdff #(31) mepc_ff (.*, .clk(e4e5_int_clk), .din(mepc_ns[31:1]), .dout(mepc[31:1])); // ---------------------------------------------------------------------- // MCAUSE (RW) - // [31:0] : Exception Cause + // [31:0] : Exception Cause `define MCAUSE 12'h342 - + assign wr_mcause_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MCAUSE); assign mcause_ns[31:0] = ( ({32{exc_or_int_valid_wb & take_nmi_wb & nmi_lsu_store_type_f}} & {32'hf000_0000}) | ({32{exc_or_int_valid_wb & take_nmi_wb & nmi_lsu_load_type_f}} & {32'hf000_0001}) | ({32{exc_or_int_valid_wb & ~take_nmi_wb}} & {interrupt_valid_wb, 26'b0, exc_cause_wb[4:0]}) | ({32{wr_mcause_wb & ~exc_or_int_valid_wb}} & dec_csr_wrdata_wb[31:0]) | - ({32{~wr_mcause_wb & ~exc_or_int_valid_wb}} & mcause[31:0]) ); + ({32{~wr_mcause_wb & ~exc_or_int_valid_wb}} & mcause[31:0]) ); rvdff #(32) mcause_ff (.*, .clk(e4e5_int_clk), .din(mcause_ns[31:0]), .dout(mcause[31:0])); @@ -1154,27 +1154,27 @@ module dec_tlu_ctl // MTVAL (RW) // [31:0] : Exception address if relevant `define MTVAL 12'h343 - + assign wr_mtval_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTVAL); assign mtval_capture_pc_wb = exc_or_int_valid_wb & (ebreak_wb | (inst_acc_wb & ~inst_acc_second_wb) | mepc_trigger_hit_sel_pc_wb) & ~take_nmi_wb; assign mtval_capture_pc_plus2_wb = exc_or_int_valid_wb & (inst_acc_wb & inst_acc_second_wb) & ~take_nmi_wb; assign mtval_capture_inst_wb = exc_or_int_valid_wb & illegal_wb & ~take_nmi_wb; assign mtval_capture_lsu_wb = exc_or_int_valid_wb & lsu_exc_valid_wb & ~take_nmi_wb; assign mtval_clear_wb = exc_or_int_valid_wb & ~mtval_capture_pc_wb & ~mtval_capture_inst_wb & ~mtval_capture_lsu_wb & ~mepc_trigger_hit_sel_pc_wb; - - + + assign mtval_ns[31:0] = (({32{mtval_capture_pc_wb}} & {pc_wb[31:1], 1'b0}) | ({32{mtval_capture_pc_plus2_wb}} & {pc_wb[31:2] + 30'b1, 2'b0}) | ({32{mtval_capture_inst_wb}} & dec_illegal_inst[31:0]) | - ({32{mtval_capture_lsu_wb}} & lsu_error_pkt_addr_wb[31:0]) | + ({32{mtval_capture_lsu_wb}} & lsu_error_pkt_addr_wb[31:0]) | ({32{wr_mtval_wb & ~interrupt_valid_wb}} & dec_csr_wrdata_wb[31:0]) | - ({32{~take_nmi_wb & ~wr_mtval_wb & ~mtval_capture_pc_wb & ~mtval_capture_inst_wb & ~mtval_clear_wb & ~mtval_capture_lsu_wb}} & mtval[31:0]) ); + ({32{~take_nmi_wb & ~wr_mtval_wb & ~mtval_capture_pc_wb & ~mtval_capture_inst_wb & ~mtval_clear_wb & ~mtval_capture_lsu_wb}} & mtval[31:0]) ); rvdff #(32) mtval_ff (.*, .clk(e4e5_int_clk), .din(mtval_ns[31:0]), .dout(mtval[31:0])); // ---------------------------------------------------------------------- - // MCGC (RW) Clock gating control + // MCGC (RW) Clock gating control // [31:9] : Reserved, reads 0x0 // [8] : misc_clk_override // [7] : dec_clk_override @@ -1185,7 +1185,7 @@ module dec_tlu_ctl // [2] : pic_clk_override // [1] : dccm_clk_override // [0] : icm_clk_override - // + // `define MCGC 12'h7f8 assign wr_mcgc_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MCGC); @@ -1207,17 +1207,17 @@ module dec_tlu_ctl // [10] : Disable dual issue // [9] : Disable pic multiple ints // [8] : Disable core ecc - // [7] : Disable secondary alu?s + // [7] : Disable secondary alu?s // [6] : Unused, 0x0 - // [5] : Disable non-blocking loads/divides - // [4] : Disable fast divide - // [3] : Disable branch prediction and return stack - // [2] : Disable write buffer coalescing - // [1] : Disable load misses that bypass the write buffer - // [0] : Disable pipelining - Enable single instruction execution - // + // [5] : Disable non-blocking loads/divides + // [4] : Disable fast divide + // [3] : Disable branch prediction and return stack + // [2] : Disable write buffer coalescing + // [1] : Disable load misses that bypass the write buffer + // [0] : Disable pipelining - Enable single instruction execution + // `define MFDC 12'h7f9 - + assign wr_mfdc_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MFDC); rvdffe #(11) mfdc_ff (.*, .en(wr_mfdc_wb), .din(dec_csr_wrdata_wb[10:0]), .dout(mfdc[10:0])); @@ -1243,7 +1243,7 @@ module dec_tlu_ctl // MRAC (RW) // [31:0] : Region Access Control Register, 16 regions, {side_effect, cachable} pairs `define MRAC 12'h7c0 - + assign wr_mrac_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MRAC); // prevent pairs of 0x11, side_effect and cacheable @@ -1264,43 +1264,43 @@ module dec_tlu_ctl dec_csr_wrdata_wb[5], dec_csr_wrdata_wb[4] & ~dec_csr_wrdata_wb[5], dec_csr_wrdata_wb[3], dec_csr_wrdata_wb[2] & ~dec_csr_wrdata_wb[3], dec_csr_wrdata_wb[1], dec_csr_wrdata_wb[0] & ~dec_csr_wrdata_wb[1]}; - + rvdffe #(32) mrac_ff (.*, .en(wr_mrac_wb), .din(mrac_in[31:0]), .dout(mrac[31:0])); // drive to LSU/IFU assign dec_tlu_mrac_ff[31:0] = mrac[31:0]; - + // ---------------------------------------------------------------------- // MDEAU (WAR0) // [31:0] : Dbus Error Address Unlock register - // + // `define MDEAU 12'hbc0 - + assign wr_mdeau_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MDEAU); - + // ---------------------------------------------------------------------- // MDSEAC (R) // [31:0] : Dbus Store Error Address Capture register - // + // `define MDSEAC 12'hfc0 - + // only capture error bus if the MDSEAC reg is not locked assign mdseac_locked_ns = mdseac_en | (mdseac_locked_f & ~wr_mdeau_wb); - + assign mdseac_en = (lsu_imprecise_error_store_any | lsu_imprecise_error_load_any) & ~mdseac_locked_f; - + rvdffe #(32) mdseac_ff (.*, .en(mdseac_en), .din(lsu_imprecise_error_addr_any[31:0]), .dout(mdseac[31:0])); - + // ---------------------------------------------------------------------- // MPMC (R0W1) // [0:0] : FW halt - // + // `define MPMC 12'h7c6 logic wr_mpmc_wb; assign wr_mpmc_wb = dec_csr_wrdata_wb[0] & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MPMC); assign fw_halt_req = wr_mpmc_wb & ~internal_dbg_halt_mode_f; - + // ---------------------------------------------------------------------- // MICECT (I-Cache error counter/threshold) // [31:27] : Icache parity error threshold @@ -1309,7 +1309,7 @@ module dec_tlu_ctl logic [31:27] csr_sat; assign csr_sat[31:27] = (dec_csr_wrdata_wb[31:27] > 5'd26) ? 5'd26 : dec_csr_wrdata_wb[31:27]; - + assign wr_micect_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MICECT); assign {micect_cout_nc, micect_inc[26:0]} = micect[26:0] + {26'b0, ic_perr_wb}; assign micect_ns = wr_micect_wb ? {csr_sat[31:27], dec_csr_wrdata_wb[26:0]} : {micect[31:27], micect_inc[26:0]}; @@ -1317,13 +1317,13 @@ module dec_tlu_ctl rvdffe #(32) micect_ff (.*, .en(wr_micect_wb | ic_perr_wb), .din(micect_ns[31:0]), .dout(micect[31:0])); assign mice_ce_req = |({32'b1 << micect[31:27]} & {5'b0, micect[26:0]}); - + // ---------------------------------------------------------------------- // MICCMECT (ICCM error counter/threshold) // [31:27] : ICCM parity error threshold // [26:0] : ICCM parity error count `define MICCMECT 12'h7f1 - + assign wr_miccmect_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MICCMECT); assign {miccmect_cout_nc, miccmect_inc[26:0]} = miccmect[26:0] + {26'b0, iccm_sbecc_wb | iccm_dma_sb_error}; assign miccmect_ns = wr_miccmect_wb ? {csr_sat[31:27], dec_csr_wrdata_wb[26:0]} : {miccmect[31:27], miccmect_inc[26:0]}; @@ -1331,13 +1331,13 @@ module dec_tlu_ctl rvdffe #(32) miccmect_ff (.*, .en(wr_miccmect_wb | iccm_sbecc_wb | iccm_dma_sb_error), .din(miccmect_ns[31:0]), .dout(miccmect[31:0])); assign miccme_ce_req = |({32'b1 << miccmect[31:27]} & {5'b0, miccmect[26:0]}); - + // ---------------------------------------------------------------------- - // MDCCMECT (DCCM error counter/threshold) + // MDCCMECT (DCCM error counter/threshold) // [31:27] : DCCM parity error threshold // [26:0] : DCCM parity error count `define MDCCMECT 12'h7f2 - + assign wr_mdccmect_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MDCCMECT); assign {mdccmect_cout_nc, mdccmect_inc[26:0]} = mdccmect[26:0] + {26'b0, lsu_single_ecc_error_wb}; assign mdccmect_ns = wr_mdccmect_wb ? {csr_sat[31:27], dec_csr_wrdata_wb[26:0]} : {mdccmect[31:27], mdccmect_inc[26:0]}; @@ -1345,13 +1345,13 @@ module dec_tlu_ctl rvdffe #(32) mdccmect_ff (.*, .en(wr_mdccmect_wb | lsu_single_ecc_error_wb), .din(mdccmect_ns[31:0]), .dout(mdccmect[31:0])); assign mdccme_ce_req = |({32'b1 << mdccmect[31:27]} & {5'b0, mdccmect[26:0]}); - + // ---------------------------------------------------------------------- // MEIVT (External Interrupt Vector Table (R/W)) // [31:10]: Base address (R/W) // [9:0] : Reserved, reads 0x0 `define MEIVT 12'hbc8 - + assign wr_meivt_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MEIVT); rvdffe #(22) meivt_ff (.*, .en(wr_meivt_wb), .din(dec_csr_wrdata_wb[31:10]), .dout(meivt[31:10])); @@ -1362,38 +1362,38 @@ module dec_tlu_ctl // [9:2] : ClaimID (R) // [1:0] : Reserved, 0x0 `define MEIHAP 12'hfc8 - + assign wr_meihap_wb = wr_meicpct_wb; rvdffe #(8) meihap_ff (.*, .en(wr_meihap_wb), .din(pic_claimid[7:0]), .dout(meihap[9:2])); - + // ---------------------------------------------------------------------- // MEICURPL (R/W) // [31:4] : Reserved (read 0x0) // [3:0] : CURRPRI - Priority level of current interrupt service routine (R/W) `define MEICURPL 12'hbcc - + assign wr_meicurpl_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MEICURPL); - assign meicurpl_ns[3:0] = wr_meicurpl_wb ? dec_csr_wrdata_wb[3:0] : meicurpl[3:0]; - + assign meicurpl_ns[3:0] = wr_meicurpl_wb ? dec_csr_wrdata_wb[3:0] : meicurpl[3:0]; + rvdff #(4) meicurpl_ff (.*, .clk(csr_wr_clk), .din(meicurpl_ns[3:0]), .dout(meicurpl[3:0])); // PIC needs this reg assign dec_tlu_meicurpl[3:0] = meicurpl[3:0]; - - + + // ---------------------------------------------------------------------- // MEICIDPL (R/W) // [31:4] : Reserved (read 0x0) // [3:0] : External Interrupt Claim ID's Priority Level Register `define MEICIDPL 12'hbcb - + assign wr_meicidpl_wb = (dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MEICIDPL)); - - assign meicidpl_ns[3:0] = wr_meicpct_wb ? pic_pl[3:0] : (wr_meicidpl_wb ? dec_csr_wrdata_wb[3:0] : meicidpl[3:0]); - + + assign meicidpl_ns[3:0] = wr_meicpct_wb ? pic_pl[3:0] : (wr_meicidpl_wb ? dec_csr_wrdata_wb[3:0] : meicidpl[3:0]); + rvdff #(4) meicidpl_ff (.*, .clk(csr_wr_clk), .din(meicidpl_ns[3:0]), .dout(meicidpl[3:0])); - + // ---------------------------------------------------------------------- // MEICPCT (Capture CLAIMID in MEIHAP and PL in MEICIDPL // [31:1] : Reserved (read 0x0) @@ -1405,12 +1405,12 @@ module dec_tlu_ctl // ---------------------------------------------------------------------- // MEIPT (External Interrupt Priority Threshold) // [31:4] : Reserved (read 0x0) - // [3:0] : PRITHRESH + // [3:0] : PRITHRESH `define MEIPT 12'hbc9 - + assign wr_meipt_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MEIPT); - assign meipt_ns[3:0] = wr_meipt_wb ? dec_csr_wrdata_wb[3:0] : meipt[3:0]; - + assign meipt_ns[3:0] = wr_meipt_wb ? dec_csr_wrdata_wb[3:0] : meipt[3:0]; + rvdff #(4) meipt_ff (.*, .clk(active_clk), .din(meipt_ns[3:0]), .dout(meipt[3:0])); // to PIC @@ -1435,35 +1435,35 @@ module dec_tlu_ctl `define DCSR 12'h7b0 logic [8:6] dcsr_cause; - // RV has clarified that 'priority 4' in the spec means top priority. + // RV has clarified that 'priority 4' in the spec means top priority. // 4. single step. 3. Debugger request. 2. Ebreak. 1. Trigger. assign dcsr_cause[8:6] = ( ({3{dcsr_single_step_done_f & ~ebreak_to_debug_mode_wb & ~trigger_hit_dmode_wb & ~dbg_halt_req}} & 3'b100) | ({3{dbg_halt_req & ~ebreak_to_debug_mode_wb & ~trigger_hit_dmode_wb}} & 3'b011) | - ({3{ebreak_to_debug_mode_wb & ~trigger_hit_dmode_wb}} & 3'b001) | + ({3{ebreak_to_debug_mode_wb & ~trigger_hit_dmode_wb}} & 3'b001) | ({3{trigger_hit_dmode_wb}} & 3'b010)); assign wr_dcsr_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DCSR); - - // Multiple halt enter requests can happen before we are halted. + + // Multiple halt enter requests can happen before we are halted. // We have to continue to upgrade based on dcsr_cause priority but we can't downgrade. logic enter_dbg_halt_req_le, dcsr_cause_upgradeable; assign dcsr_cause_upgradeable = internal_dbg_halt_mode_f & (dcsr[8:6] == 3'b011); assign enter_dbg_halt_req_le = enter_dbg_halt_req & (~dbg_tlu_halted | dcsr_cause_upgradeable); assign nmi_in_debug_mode = nmi_int_detected_f & internal_dbg_halt_mode_f; - assign dcsr_ns[15:2] = enter_dbg_halt_req_le ? {dcsr[15:9], dcsr_cause[8:6], dcsr[5:2]} : + assign dcsr_ns[15:2] = enter_dbg_halt_req_le ? {dcsr[15:9], dcsr_cause[8:6], dcsr[5:2]} : (wr_dcsr_wb ? {dec_csr_wrdata_wb[15], 3'b0, dec_csr_wrdata_wb[11:10], 1'b0, dcsr[8:6], 2'b00, nmi_in_debug_mode | dcsr[3], dec_csr_wrdata_wb[2]} : {dcsr[15:4], nmi_in_debug_mode, dcsr[2]}); - + rvdffe #(14) dcsr_ff (.*, .en(enter_dbg_halt_req_le | wr_dcsr_wb | internal_dbg_halt_mode | take_nmi_wb), .din(dcsr_ns[15:2]), .dout(dcsr[15:2])); // ---------------------------------------------------------------------- // DPC (R/W) (Only accessible in debug mode) // [31:0] : Debug PC `define DPC 12'h7b1 - + assign wr_dpc_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DPC); assign dpc_capture_npc = dbg_tlu_halted & ~dbg_tlu_halted_f & ~request_debug_mode_done_f; assign dpc_capture_pc = request_debug_mode_wb; @@ -1471,7 +1471,7 @@ module dec_tlu_ctl assign dpc_ns[31:1] = ( ({31{~dpc_capture_pc & ~dpc_capture_npc & wr_dpc_wb}} & dec_csr_wrdata_wb[31:1]) | ({31{dpc_capture_pc}} & pc_wb[31:1]) | ({31{~dpc_capture_pc & dpc_capture_npc}} & npc_wb[31:1]) ); - + rvdffe #(31) dpc_ff (.*, .en(wr_dpc_wb | dpc_capture_pc | dpc_capture_npc), .din(dpc_ns[31:1]), .dout(dpc[31:1])); // ---------------------------------------------------------------------- @@ -1487,7 +1487,7 @@ module dec_tlu_ctl assign dicawics_ns[18:2] = {dec_csr_wrdata_wb[24], dec_csr_wrdata_wb[21:20], dec_csr_wrdata_wb[15:2]}; assign wr_dicawics_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DICAWICS); - + rvdffe #(17) dicawics_ff (.*, .en(wr_dicawics_wb), .din(dicawics_ns[18:2]), .dout(dicawics[18:2])); // ---------------------------------------------------------------------- @@ -1507,7 +1507,7 @@ module dec_tlu_ctl assign dicad0_ns[31:0] = wr_dicad0_wb ? dec_csr_wrdata_wb[31:0] : ifu_ic_debug_rd_data[31:0]; assign wr_dicad0_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DICAD0); - + rvdffe #(32) dicad0_ff (.*, .en(wr_dicad0_wb | ifu_ic_debug_rd_data_valid), .din(dicad0_ns[31:0]), .dout(dicad0[31:0])); @@ -1520,7 +1520,7 @@ module dec_tlu_ctl assign dicad1_ns[9:0] = wr_dicad1_wb ? dec_csr_wrdata_wb[9:0] : ifu_ic_debug_rd_data[41:32]; assign wr_dicad1_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DICAD1); - + rvdffs #(10) dicad1_ff (.*, .clk(active_clk), .en(wr_dicad1_wb | ifu_ic_debug_rd_data_valid), .din(dicad1_ns[9:0]), .dout(dicad1[9:0])); `else @@ -1532,16 +1532,16 @@ module dec_tlu_ctl assign dicad1_ns[1:0] = wr_dicad1_wb ? dec_csr_wrdata_wb[1:0] : ifu_ic_debug_rd_data[33:32]; assign wr_dicad1_wb = allow_dbg_halt_csr_write & dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `DICAD1); - + rvdffs #(2) dicad1_ff (.*, .clk(active_clk), .en(wr_dicad1_wb | ifu_ic_debug_rd_data_valid), .din(dicad1_ns[1:0]), .dout(dicad1[1:0])); `endif // ---------------------------------------------------------------------- // DICAGO (R/W) (Only accessible in debug mode) // [0] : Go `define DICAGO 12'h7cb - + `ifdef RV_ICACHE_ECC - assign dec_tlu_ic_diag_pkt.icache_wrdata[41:0] = {dicad1[9:0], dicad0[31:0]}; + assign dec_tlu_ic_diag_pkt.icache_wrdata[41:0] = {dicad1[9:0], dicad0[31:0]}; `else assign dec_tlu_ic_diag_pkt.icache_wrdata[33:0] = {dicad1[1:0], dicad0[31:0]}; `endif @@ -1560,12 +1560,12 @@ module dec_tlu_ctl // MTSEL (R/W) // [1:0] : Trigger select : 00, 01, 10 are data/address triggers. 11 is inst count `define MTSEL 12'h7a0 - + assign wr_mtsel_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTSEL); - assign mtsel_ns[1:0] = wr_mtsel_wb ? {dec_csr_wrdata_wb[1:0]} : mtsel[1:0]; + assign mtsel_ns[1:0] = wr_mtsel_wb ? {dec_csr_wrdata_wb[1:0]} : mtsel[1:0]; rvdff #(2) mtsel_ff (.*, .clk(csr_wr_clk), .din(mtsel_ns[1:0]), .dout(mtsel[1:0])); - + // ---------------------------------------------------------------------- // MTDATA1 (R/W) // [31:0] : Trigger Data 1 @@ -1606,76 +1606,76 @@ module dec_tlu_ctl assign tdata_opcode = dec_csr_wrdata_wb[2] & ~dec_csr_wrdata_wb[19]; // don't allow clearing DMODE and action=1 assign tdata_action = (dec_csr_wrdata_wb[27] & dbg_tlu_halted_f) & dec_csr_wrdata_wb[12]; - - assign tdata_wrdata_wb[9:0] = {dec_csr_wrdata_wb[27] & dbg_tlu_halted_f, + + assign tdata_wrdata_wb[9:0] = {dec_csr_wrdata_wb[27] & dbg_tlu_halted_f, dec_csr_wrdata_wb[20:19], - tdata_action, - dec_csr_wrdata_wb[11], - dec_csr_wrdata_wb[7:6], - tdata_opcode, - dec_csr_wrdata_wb[1], + tdata_action, + dec_csr_wrdata_wb[11], + dec_csr_wrdata_wb[7:6], + tdata_opcode, + dec_csr_wrdata_wb[1], tdata_load}; // If the DMODE bit is set, tdata1 can only be updated in debug_mode assign wr_mtdata1_t0_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTDATA1) & (mtsel[1:0] == 2'b0) & (~mtdata1_t0[`MTDATA1_DMODE] | dbg_tlu_halted_f); - assign mtdata1_t0_ns[9:0] = wr_mtdata1_t0_wb ? tdata_wrdata_wb[9:0] : - {mtdata1_t0[9], update_hit_bit_wb[0] | mtdata1_t0[8], mtdata1_t0[7:0]}; + assign mtdata1_t0_ns[9:0] = wr_mtdata1_t0_wb ? tdata_wrdata_wb[9:0] : + {mtdata1_t0[9], update_hit_bit_wb[0] | mtdata1_t0[8], mtdata1_t0[7:0]}; assign wr_mtdata1_t1_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTDATA1) & (mtsel[1:0] == 2'b01) & (~mtdata1_t1[`MTDATA1_DMODE] | dbg_tlu_halted_f); - assign mtdata1_t1_ns[9:0] = wr_mtdata1_t1_wb ? tdata_wrdata_wb[9:0] : - {mtdata1_t1[9], update_hit_bit_wb[1] | mtdata1_t1[8], mtdata1_t1[7:0]}; + assign mtdata1_t1_ns[9:0] = wr_mtdata1_t1_wb ? tdata_wrdata_wb[9:0] : + {mtdata1_t1[9], update_hit_bit_wb[1] | mtdata1_t1[8], mtdata1_t1[7:0]}; assign wr_mtdata1_t2_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTDATA1) & (mtsel[1:0] == 2'b10) & (~mtdata1_t2[`MTDATA1_DMODE] | dbg_tlu_halted_f); - assign mtdata1_t2_ns[9:0] = wr_mtdata1_t2_wb ? tdata_wrdata_wb[9:0] : - {mtdata1_t2[9], update_hit_bit_wb[2] | mtdata1_t2[8], mtdata1_t2[7:0]}; + assign mtdata1_t2_ns[9:0] = wr_mtdata1_t2_wb ? tdata_wrdata_wb[9:0] : + {mtdata1_t2[9], update_hit_bit_wb[2] | mtdata1_t2[8], mtdata1_t2[7:0]}; assign wr_mtdata1_t3_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTDATA1) & (mtsel[1:0] == 2'b11) & (~mtdata1_t3[`MTDATA1_DMODE] | dbg_tlu_halted_f); - assign mtdata1_t3_ns[9:0] = wr_mtdata1_t3_wb ? tdata_wrdata_wb[9:0] : - {mtdata1_t3[9], update_hit_bit_wb[3] | mtdata1_t3[8], mtdata1_t3[7:0]}; + assign mtdata1_t3_ns[9:0] = wr_mtdata1_t3_wb ? tdata_wrdata_wb[9:0] : + {mtdata1_t3[9], update_hit_bit_wb[3] | mtdata1_t3[8], mtdata1_t3[7:0]}; + - rvdff #(10) mtdata1_t0_ff (.*, .clk(active_clk), .din(mtdata1_t0_ns[9:0]), .dout(mtdata1_t0[9:0])); rvdff #(10) mtdata1_t1_ff (.*, .clk(active_clk), .din(mtdata1_t1_ns[9:0]), .dout(mtdata1_t1[9:0])); rvdff #(10) mtdata1_t2_ff (.*, .clk(active_clk), .din(mtdata1_t2_ns[9:0]), .dout(mtdata1_t2[9:0])); rvdff #(10) mtdata1_t3_ff (.*, .clk(active_clk), .din(mtdata1_t3_ns[9:0]), .dout(mtdata1_t3[9:0])); - + assign mtdata1_tsel_out[31:0] = ( ({32{(mtsel[1:0] == 2'b00)}} & {4'h2, mtdata1_t0[9], 6'b011111, mtdata1_t0[8:7], 6'b0, mtdata1_t0[6:5], 3'b0, mtdata1_t0[4:3], 3'b0, mtdata1_t0[2:0]}) | ({32{(mtsel[1:0] == 2'b01)}} & {4'h2, mtdata1_t1[9], 6'b011111, mtdata1_t1[8:7], 6'b0, mtdata1_t1[6:5], 3'b0, mtdata1_t1[4:3], 3'b0, mtdata1_t1[2:0]}) | ({32{(mtsel[1:0] == 2'b10)}} & {4'h2, mtdata1_t2[9], 6'b011111, mtdata1_t2[8:7], 6'b0, mtdata1_t2[6:5], 3'b0, mtdata1_t2[4:3], 3'b0, mtdata1_t2[2:0]}) | ({32{(mtsel[1:0] == 2'b11)}} & {4'h2, mtdata1_t3[9], 6'b011111, mtdata1_t3[8:7], 6'b0, mtdata1_t3[6:5], 3'b0, mtdata1_t3[4:3], 3'b0, mtdata1_t3[2:0]})); - + assign trigger_pkt_any[0].select = mtdata1_t0[`MTDATA1_SEL]; assign trigger_pkt_any[0].match = mtdata1_t0[`MTDATA1_MATCH]; assign trigger_pkt_any[0].store = mtdata1_t0[`MTDATA1_ST]; - assign trigger_pkt_any[0].load = mtdata1_t0[`MTDATA1_LD]; + assign trigger_pkt_any[0].load = mtdata1_t0[`MTDATA1_LD]; assign trigger_pkt_any[0].execute = mtdata1_t0[`MTDATA1_EXE]; assign trigger_pkt_any[0].m = mtdata1_t0[`MTDATA1_M_ENABLED]; - + assign trigger_pkt_any[1].select = mtdata1_t1[`MTDATA1_SEL]; assign trigger_pkt_any[1].match = mtdata1_t1[`MTDATA1_MATCH]; assign trigger_pkt_any[1].store = mtdata1_t1[`MTDATA1_ST]; assign trigger_pkt_any[1].load = mtdata1_t1[`MTDATA1_LD]; assign trigger_pkt_any[1].execute = mtdata1_t1[`MTDATA1_EXE]; assign trigger_pkt_any[1].m = mtdata1_t1[`MTDATA1_M_ENABLED]; - + assign trigger_pkt_any[2].select = mtdata1_t2[`MTDATA1_SEL]; assign trigger_pkt_any[2].match = mtdata1_t2[`MTDATA1_MATCH]; assign trigger_pkt_any[2].store = mtdata1_t2[`MTDATA1_ST]; assign trigger_pkt_any[2].load = mtdata1_t2[`MTDATA1_LD]; assign trigger_pkt_any[2].execute = mtdata1_t2[`MTDATA1_EXE]; assign trigger_pkt_any[2].m = mtdata1_t2[`MTDATA1_M_ENABLED]; - + assign trigger_pkt_any[3].select = mtdata1_t3[`MTDATA1_SEL]; assign trigger_pkt_any[3].match = mtdata1_t3[`MTDATA1_MATCH]; assign trigger_pkt_any[3].store = mtdata1_t3[`MTDATA1_ST]; assign trigger_pkt_any[3].load = mtdata1_t3[`MTDATA1_LD]; assign trigger_pkt_any[3].execute = mtdata1_t3[`MTDATA1_EXE]; assign trigger_pkt_any[3].m = mtdata1_t3[`MTDATA1_M_ENABLED]; - - - + + + // ---------------------------------------------------------------------- // MTDATA2 (R/W) // [31:0] : Trigger Data 2 @@ -1691,12 +1691,12 @@ module dec_tlu_ctl rvdffe #(32) mtdata2_t1_ff (.*, .en(wr_mtdata2_t1_wb), .din(dec_csr_wrdata_wb[31:0]), .dout(mtdata2_t1[31:0])); rvdffe #(32) mtdata2_t2_ff (.*, .en(wr_mtdata2_t2_wb), .din(dec_csr_wrdata_wb[31:0]), .dout(mtdata2_t2[31:0])); rvdffe #(32) mtdata2_t3_ff (.*, .en(wr_mtdata2_t3_wb), .din(dec_csr_wrdata_wb[31:0]), .dout(mtdata2_t3[31:0])); - + assign mtdata2_tsel_out[31:0] = ( ({32{(mtsel[1:0] == 2'b00)}} & mtdata2_t0[31:0]) | ({32{(mtsel[1:0] == 2'b01)}} & mtdata2_t1[31:0]) | ({32{(mtsel[1:0] == 2'b10)}} & mtdata2_t2[31:0]) | ({32{(mtsel[1:0] == 2'b11)}} & mtdata2_t3[31:0])); - + assign trigger_pkt_any[0].tdata2[31:0] = mtdata2_t0[31:0]; assign trigger_pkt_any[1].tdata2[31:0] = mtdata2_t1[31:0]; assign trigger_pkt_any[2].tdata2[31:0] = mtdata2_t2[31:0]; @@ -1715,21 +1715,21 @@ module dec_tlu_ctl `define MHPME_INST_COMMIT_32B 6'd6 `define MHPME_INST_ALIGNED 6'd7 // OOP `define MHPME_INST_DECODED 6'd8 // OOP - `define MHPME_INST_MUL 6'd9 + `define MHPME_INST_MUL 6'd9 `define MHPME_INST_DIV 6'd10 - `define MHPME_INST_LOAD 6'd11 - `define MHPME_INST_STORE 6'd12 - `define MHPME_INST_MALOAD 6'd13 - `define MHPME_INST_MASTORE 6'd14 - `define MHPME_INST_ALU 6'd15 - `define MHPME_INST_CSRREAD 6'd16 - `define MHPME_INST_CSRRW 6'd17 - `define MHPME_INST_CSRWRITE 6'd18 - `define MHPME_INST_EBREAK 6'd19 - `define MHPME_INST_ECALL 6'd20 - `define MHPME_INST_FENCE 6'd21 - `define MHPME_INST_FENCEI 6'd22 - `define MHPME_INST_MRET 6'd23 + `define MHPME_INST_LOAD 6'd11 + `define MHPME_INST_STORE 6'd12 + `define MHPME_INST_MALOAD 6'd13 + `define MHPME_INST_MASTORE 6'd14 + `define MHPME_INST_ALU 6'd15 + `define MHPME_INST_CSRREAD 6'd16 + `define MHPME_INST_CSRRW 6'd17 + `define MHPME_INST_CSRWRITE 6'd18 + `define MHPME_INST_EBREAK 6'd19 + `define MHPME_INST_ECALL 6'd20 + `define MHPME_INST_FENCE 6'd21 + `define MHPME_INST_FENCEI 6'd22 + `define MHPME_INST_MRET 6'd23 `define MHPME_INST_BRANCH 6'd24 `define MHPME_BRANCH_MP 6'd25 `define MHPME_BRANCH_TAKEN 6'd26 @@ -1757,9 +1757,9 @@ module dec_tlu_ctl `define MHPME_DBUS_STALL 6'd48 // OOP `define MHPME_INT_DISABLED 6'd49 // OOP `define MHPME_INT_STALLED 6'd50 // OOP - - - logic [3:0][1:0] mhpmc_inc_e4, mhpmc_inc_wb; + + + logic [3:0][1:0] mhpmc_inc_e4, mhpmc_inc_wb; logic [3:0][5:0] mhpme_vec; logic mhpmc3_wr_en0, mhpmc3_wr_en1, mhpmc3_wr_en; logic mhpmc4_wr_en0, mhpmc4_wr_en1, mhpmc4_wr_en; @@ -1770,7 +1770,7 @@ module dec_tlu_ctl logic mhpmc5h_wr_en0, mhpmc5h_wr_en; logic mhpmc6h_wr_en0, mhpmc6h_wr_en; logic [63:0] mhpmc3_incr, mhpmc4_incr, mhpmc5_incr, mhpmc6_incr; - + // Pack the event selects into a vector for genvar assign mhpme_vec[0][5:0] = mhpme3[5:0]; assign mhpme_vec[1][5:0] = mhpme4[5:0]; @@ -1781,11 +1781,11 @@ module dec_tlu_ctl logic [3:0] pmu_i0_itype_qual, pmu_i1_itype_qual; assign pmu_i0_itype_qual[3:0] = dec_tlu_packet_e4.pmu_i0_itype[3:0] & {4{tlu_i0_commit_cmt}}; assign pmu_i1_itype_qual[3:0] = dec_tlu_packet_e4.pmu_i1_itype[3:0] & {4{tlu_i1_commit_cmt}}; - + // Generate the muxed incs for all counters based on event type for (genvar i=0 ; i < 4; i++) begin - assign mhpmc_inc_e4[i][1:0] = {2{mgpmc}} & - ( + assign mhpmc_inc_e4[i][1:0] = {2{mgpmc}} & + ( ({2{(mhpme_vec[i][5:0] == `MHPME_CLK_ACTIVE )}} & 2'b01) | ({2{(mhpme_vec[i][5:0] == `MHPME_ICACHE_HIT )}} & {1'b0, ifu_pmu_ic_hit}) | ({2{(mhpme_vec[i][5:0] == `MHPME_ICACHE_MISS )}} & {1'b0, ifu_pmu_ic_miss}) | @@ -1800,9 +1800,9 @@ module dec_tlu_ctl ({2{(mhpme_vec[i][5:0] == `MHPME_INST_DIV )}} & {1'b0, dec_tlu_packet_e4.pmu_divide}) | ({2{(mhpme_vec[i][5:0] == `MHPME_INST_LOAD )}} & {(pmu_i1_itype_qual[3:0] == LOAD), (pmu_i0_itype_qual[3:0] == LOAD)}) | ({2{(mhpme_vec[i][5:0] == `MHPME_INST_STORE )}} & {(pmu_i1_itype_qual[3:0] == STORE), (pmu_i0_itype_qual[3:0] == STORE)}) | - ({2{(mhpme_vec[i][5:0] == `MHPME_INST_MALOAD )}} & {(pmu_i1_itype_qual[3:0] == LOAD), (pmu_i0_itype_qual[3:0] == LOAD)} & + ({2{(mhpme_vec[i][5:0] == `MHPME_INST_MALOAD )}} & {(pmu_i1_itype_qual[3:0] == LOAD), (pmu_i0_itype_qual[3:0] == LOAD)} & {2{dec_tlu_packet_e4.pmu_lsu_misaligned}}) | - ({2{(mhpme_vec[i][5:0] == `MHPME_INST_MASTORE )}} & {(pmu_i1_itype_qual[3:0] == STORE), (pmu_i0_itype_qual[3:0] == STORE)} & + ({2{(mhpme_vec[i][5:0] == `MHPME_INST_MASTORE )}} & {(pmu_i1_itype_qual[3:0] == STORE), (pmu_i0_itype_qual[3:0] == STORE)} & {2{dec_tlu_packet_e4.pmu_lsu_misaligned}}) | ({2{(mhpme_vec[i][5:0] == `MHPME_INST_ALU )}} & {(pmu_i1_itype_qual[3:0] == ALU), (pmu_i0_itype_qual[3:0] == ALU)}) | ({2{(mhpme_vec[i][5:0] == `MHPME_INST_CSRREAD )}} & {1'b0, (pmu_i0_itype_qual[3:0] == CSRREAD)}) | @@ -1840,7 +1840,7 @@ module dec_tlu_ctl ({2{(mhpme_vec[i][5:0] == `MHPME_IBUS_STALL )}} & {1'b0, ifu_pmu_bus_busy}) | ({2{(mhpme_vec[i][5:0] == `MHPME_DBUS_STALL )}} & {1'b0, lsu_pmu_bus_busy}) | ({2{(mhpme_vec[i][5:0] == `MHPME_INT_DISABLED )}} & {1'b0, ~mstatus[`MSTATUS_MIE]}) | - ({2{(mhpme_vec[i][5:0] == `MHPME_INT_STALLED )}} & {1'b0, ~mstatus[`MSTATUS_MIE] & |(mip[3:0] & mie[3:0])}) + ({2{(mhpme_vec[i][5:0] == `MHPME_INT_STALLED )}} & {1'b0, ~mstatus[`MSTATUS_MIE] & |(mip[3:0] & mie[3:0])}) ); end @@ -1850,7 +1850,7 @@ module dec_tlu_ctl rvdff #(2) pmu3inc_ff (.*, .clk(free_clk), .din(mhpmc_inc_e4[3][1:0]), .dout(mhpmc_inc_wb[3][1:0])); assign perfcnt_halted = ((dec_tlu_dbg_halted & dcsr[`DCSR_STOPC]) | dec_tlu_pmu_fw_halted); - + assign dec_tlu_perfcnt0 = mhpmc_inc_wb[0][0] & ~perfcnt_halted; assign dec_tlu_perfcnt1 = mhpmc_inc_wb[1][0] & ~perfcnt_halted; assign dec_tlu_perfcnt2 = mhpmc_inc_wb[2][0] & ~perfcnt_halted; @@ -1861,11 +1861,11 @@ module dec_tlu_ctl // [63:32][31:0] : Hardware Performance Monitor Counter 3 `define MHPMC3 12'hB03 `define MHPMC3H 12'hB83 - + assign mhpmc3_wr_en0 = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPMC3); assign mhpmc3_wr_en1 = ~perfcnt_halted & (|(mhpmc_inc_wb[0][1:0])); assign mhpmc3_wr_en = mhpmc3_wr_en0 | mhpmc3_wr_en1; - assign mhpmc3_incr[63:0] = {mhpmc3h[31:0],mhpmc3[31:0]} + {63'b0,mhpmc_inc_wb[0][1]} + {63'b0,mhpmc_inc_wb[0][0]}; + assign mhpmc3_incr[63:0] = {mhpmc3h[31:0],mhpmc3[31:0]} + {63'b0,mhpmc_inc_wb[0][1]} + {63'b0,mhpmc_inc_wb[0][0]}; assign mhpmc3_ns[31:0] = mhpmc3_wr_en0 ? dec_csr_wrdata_wb[31:0] : mhpmc3_incr[31:0]; rvdffe #(32) mhpmc3_ff (.*, .en(mhpmc3_wr_en), .din(mhpmc3_ns[31:0]), .dout(mhpmc3[31:0])); @@ -1879,11 +1879,11 @@ module dec_tlu_ctl // [63:32][31:0] : Hardware Performance Monitor Counter 4 `define MHPMC4 12'hB04 `define MHPMC4H 12'hB84 - + assign mhpmc4_wr_en0 = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPMC4); assign mhpmc4_wr_en1 = ~perfcnt_halted & (|(mhpmc_inc_wb[1][1:0])); assign mhpmc4_wr_en = mhpmc4_wr_en0 | mhpmc4_wr_en1; - assign mhpmc4_incr[63:0] = {mhpmc4h[31:0],mhpmc4[31:0]} + {63'b0,mhpmc_inc_wb[1][1]} + {63'b0,mhpmc_inc_wb[1][0]}; + assign mhpmc4_incr[63:0] = {mhpmc4h[31:0],mhpmc4[31:0]} + {63'b0,mhpmc_inc_wb[1][1]} + {63'b0,mhpmc_inc_wb[1][0]}; assign mhpmc4_ns[31:0] = mhpmc4_wr_en0 ? dec_csr_wrdata_wb[31:0] : mhpmc4_incr[31:0]; rvdffe #(32) mhpmc4_ff (.*, .en(mhpmc4_wr_en), .din(mhpmc4_ns[31:0]), .dout(mhpmc4[31:0])); @@ -1897,11 +1897,11 @@ module dec_tlu_ctl // [63:32][31:0] : Hardware Performance Monitor Counter 5 `define MHPMC5 12'hB05 `define MHPMC5H 12'hB85 - + assign mhpmc5_wr_en0 = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPMC5); assign mhpmc5_wr_en1 = ~perfcnt_halted & (|(mhpmc_inc_wb[2][1:0])); assign mhpmc5_wr_en = mhpmc5_wr_en0 | mhpmc5_wr_en1; - assign mhpmc5_incr[63:0] = {mhpmc5h[31:0],mhpmc5[31:0]} + {63'b0,mhpmc_inc_wb[2][1]} + {63'b0,mhpmc_inc_wb[2][0]}; + assign mhpmc5_incr[63:0] = {mhpmc5h[31:0],mhpmc5[31:0]} + {63'b0,mhpmc_inc_wb[2][1]} + {63'b0,mhpmc_inc_wb[2][0]}; assign mhpmc5_ns[31:0] = mhpmc5_wr_en0 ? dec_csr_wrdata_wb[31:0] : mhpmc5_incr[31:0]; rvdffe #(32) mhpmc5_ff (.*, .en(mhpmc5_wr_en), .din(mhpmc5_ns[31:0]), .dout(mhpmc5[31:0])); @@ -1915,11 +1915,11 @@ module dec_tlu_ctl // [63:32][31:0] : Hardware Performance Monitor Counter 6 `define MHPMC6 12'hB06 `define MHPMC6H 12'hB86 - + assign mhpmc6_wr_en0 = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPMC6); assign mhpmc6_wr_en1 = ~perfcnt_halted & (|(mhpmc_inc_wb[3][1:0])); assign mhpmc6_wr_en = mhpmc6_wr_en0 | mhpmc6_wr_en1; - assign mhpmc6_incr[63:0] = {mhpmc6h[31:0],mhpmc6[31:0]} + {63'b0,mhpmc_inc_wb[3][1]} + {63'b0,mhpmc_inc_wb[3][0]}; + assign mhpmc6_incr[63:0] = {mhpmc6h[31:0],mhpmc6[31:0]} + {63'b0,mhpmc_inc_wb[3][1]} + {63'b0,mhpmc_inc_wb[3][0]}; assign mhpmc6_ns[31:0] = mhpmc6_wr_en0 ? dec_csr_wrdata_wb[31:0] : mhpmc6_incr[31:0]; rvdffe #(32) mhpmc6_ff (.*, .en(mhpmc6_wr_en), .din(mhpmc6_ns[31:0]), .dout(mhpmc6[31:0])); @@ -1936,28 +1936,28 @@ module dec_tlu_ctl // we only have 50 events, HPME* are WARL so saturate at 50 logic [5:0] event_saturate_wb; assign event_saturate_wb[5:0] = ((dec_csr_wrdata_wb[5:0] > 6'd50) | (|dec_csr_wrdata_wb[31:6])) ? 6'd50 : dec_csr_wrdata_wb[5:0]; - + assign wr_mhpme3_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPME3); rvdffs #(6) mhpme3_ff (.*, .clk(active_clk), .en(wr_mhpme3_wb), .din(event_saturate_wb[5:0]), .dout(mhpme3[5:0])); // ---------------------------------------------------------------------- // MHPME4(RW) // [5:0] : Hardware Performance Monitor Event 4 `define MHPME4 12'h324 - + assign wr_mhpme4_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPME4); rvdffs #(6) mhpme4_ff (.*, .clk(active_clk), .en(wr_mhpme4_wb), .din(event_saturate_wb[5:0]), .dout(mhpme4[5:0])); // ---------------------------------------------------------------------- // MHPME5(RW) // [5:0] : Hardware Performance Monitor Event 5 `define MHPME5 12'h325 - + assign wr_mhpme5_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPME5); rvdffs #(6) mhpme5_ff (.*, .clk(active_clk), .en(wr_mhpme5_wb), .din(event_saturate_wb[5:0]), .dout(mhpme5[5:0])); // ---------------------------------------------------------------------- // MHPME6(RW) // [5:0] : Hardware Performance Monitor Event 6 `define MHPME6 12'h326 - + assign wr_mhpme6_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MHPME6); rvdffs #(6) mhpme6_ff (.*, .clk(active_clk), .en(wr_mhpme6_wb), .din(event_saturate_wb[5:0]), .dout(mhpme6[5:0])); @@ -1976,20 +1976,20 @@ module dec_tlu_ctl assign wr_mgpmc_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MGPMC); rvdffs #(1) mgpmc_ff (.*, .clk(active_clk), .en(wr_mgpmc_wb), .din(~dec_csr_wrdata_wb[0]), .dout(mgpmc_b)); assign mgpmc = ~mgpmc_b; - + //-------------------------------------------------------------------------------- // trace //-------------------------------------------------------------------------------- logic usoc_tclk; - - rvclkhdr usoctrace_cgc ( .en(i0_valid_wb | exc_or_int_valid_wb | interrupt_valid_wb | dec_tlu_i0_valid_wb1 | + + rvclkhdr usoctrace_cgc ( .en(i0_valid_wb | exc_or_int_valid_wb | interrupt_valid_wb | dec_tlu_i0_valid_wb1 | dec_tlu_i0_exc_valid_wb1 | dec_tlu_i1_exc_valid_wb1 | dec_tlu_int_valid_wb1 | clk_override), .l1clk(usoc_tclk), .* ); - rvdff #(10) traceff (.*, .clk(usoc_tclk), - .din ({i0_valid_wb, i1_valid_wb, + rvdff #(10) traceff (.*, .clk(usoc_tclk), + .din ({i0_valid_wb, i1_valid_wb, i0_exception_valid_wb | lsu_i0_exc_wb, ~(i0_exception_valid_wb | lsu_i0_exc_wb) & exc_or_int_valid_wb & ~interrupt_valid_wb, exc_cause_wb[4:0], - interrupt_valid_wb}), + interrupt_valid_wb}), .dout({dec_tlu_i0_valid_wb1, dec_tlu_i1_valid_wb1, dec_tlu_i0_exc_valid_wb1, dec_tlu_i1_exc_valid_wb1, dec_tlu_exc_cause_wb1[4:0], @@ -2000,7 +2000,7 @@ module dec_tlu_ctl // end trace //-------------------------------------------------------------------------------- - + // ---------------------------------------------------------------------- // CSR read mux // ---------------------------------------------------------------------- @@ -2363,15 +2363,15 @@ assign legal_csr = (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[ - + assign dec_tlu_presync_d = presync & dec_csr_any_unq_d & ~dec_csr_wen_unq_d; assign dec_tlu_postsync_d = postsync & dec_csr_any_unq_d; assign valid_csr = ( legal_csr & (~(csr_dcsr | csr_dpc | csr_dmst | csr_dicawics | csr_dicad0 | csr_dicad1 | csr_dicago) | dbg_tlu_halted_f)); - -assign dec_csr_legal_d = ( dec_csr_any_unq_d & + +assign dec_csr_legal_d = ( dec_csr_any_unq_d & valid_csr & // of a valid CSR ~(dec_csr_wen_unq_d & (csr_mvendorid | csr_marchid | csr_mimpid | csr_mhartid | csr_mdseac | csr_meihap)) // that's not a write to a RO CSR - ); + ); // CSR read mux assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) | ({32{csr_mvendorid}} & 32'h00000045) | @@ -2424,8 +2424,8 @@ assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) | ({32{csr_mgpmc}} & {31'b0, mgpmc}) ); - - + + `undef MSTATUS_MIE `undef MISA `undef MVENDORID @@ -2457,6 +2457,6 @@ assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) | `undef MEIPT `undef MEICURPL - + endmodule // dec_tlu_ctl diff --git a/design/dec/dec_trigger.sv b/design/dec/dec_trigger.sv index eafb51c..fcd67d0 100644 --- a/design/dec/dec_trigger.sv +++ b/design/dec/dec_trigger.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,8 +16,8 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: DEC Trigger Logic // Comments: // @@ -30,23 +30,23 @@ module dec_trigger input trigger_pkt_t [3:0] trigger_pkt_any, // Packet from tlu. 'select':0-pc,1-Opcode 'Execute' needs to be set for dec triggers to fire. 'match'-1 do mask, 0: full match input logic [31:1] dec_i0_pc_d, // i0 pc - input logic [31:1] dec_i1_pc_d, // i1 pc - + input logic [31:1] dec_i1_pc_d, // i1 pc + output logic [3:0] dec_i0_trigger_match_d, - output logic [3:0] dec_i1_trigger_match_d + output logic [3:0] dec_i1_trigger_match_d ); logic [3:0][31:0] dec_i0_match_data; logic [3:0] dec_i0_trigger_data_match; logic [3:0][31:0] dec_i1_match_data; logic [3:0] dec_i1_trigger_data_match; - + 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 assign dec_i1_match_data[i][31:0] = ({32{~trigger_pkt_any[i].select & trigger_pkt_any[i].execute}} & {dec_i1_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])); rvmaskandmatch trigger_i1_match (.mask(trigger_pkt_any[i].tdata2[31:0]), .data(dec_i1_match_data[i][31:0]), .masken(trigger_pkt_any[i].match), .match(dec_i1_trigger_data_match[i])); assign dec_i0_trigger_match_d[i] = trigger_pkt_any[i].execute & dec_i0_trigger_data_match[i]; diff --git a/design/dec/decode b/design/dec/decode index e4e85dd..46637f4 100644 --- a/design/dec/decode +++ b/design/dec/decode @@ -3,21 +3,21 @@ add = [0000000..........000.....0110011] addi = [.................000.....0010011] - + sub = [0100000..........000.....0110011] - + and = [0000000..........111.....0110011] andi = [.................111.....0010011] - + or = [0000000..........110.....0110011] ori = [.................110.....0010011] - + xor = [0000000..........100.....0110011] xori = [.................100.....0010011] - + sll = [0000000..........001.....0110011] slli = [0000000..........001.....0010011] - + sra = [0100000..........101.....0110011] srai = [0100000..........101.....0010011] @@ -26,30 +26,30 @@ srli = [0000000..........101.....0010011] lui = [.........................0110111] auipc= [.........................0010111] - + slt = [0000000..........010.....0110011] sltu = [0000000..........011.....0110011] slti = [.................010.....0010011] sltiu= [.................011.....0010011] - + beq = [.................000.....1100011] bne = [.................001.....1100011] bge = [.................101.....1100011] blt = [.................100.....1100011] bgeu = [.................111.....1100011] bltu = [.................110.....1100011] - + jal = [.........................1101111] jalr = [.................000.....1100111] - + lb = [.................000.....0000011] lh = [.................001.....0000011] lw = [.................010.....0000011] - + sb = [.................000.....0100011] sh = [.................001.....0100011] sw = [.................010.....0100011] - + lbu = [.................100.....0000011] lhu = [.................101.....0000011] @@ -117,7 +117,7 @@ rem = [0000001..........110.....0110011] remu = [0000001..........111.....0110011] -.input +.input rv32i = { i[31] @@ -188,7 +188,7 @@ rv32i = { by half word - csr_read + csr_read csr_clr csr_set csr_write @@ -294,22 +294,22 @@ rv32i[csrrc_ro] = { alu rd csr_read lor } # put csr on rs2 and make rs1 0's into alu. Save rs1 for csr_clr later rv32i[csrrc_rw{0-4}] = { alu rd csr_read rs1 csr_clr lor presync postsync } - + rv32i[csrrci_ro] = { alu rd csr_read lor } - + rv32i[csrrci_rw{0-4}] = { alu rd csr_read rs1 csr_clr csr_imm lor presync postsync } - + rv32i[csrrs_ro] = { alu rd csr_read lor } - + rv32i[csrrs_rw{0-4}] = { alu rd csr_read rs1 csr_set lor presync postsync } - + rv32i[csrrsi_ro] = { alu rd csr_read lor } - + rv32i[csrrsi_rw{0-4}] = { alu rd csr_read rs1 csr_set csr_imm lor presync postsync } - + rv32i[csrrw{0-4}] = { alu rd csr_read rs1 csr_write lor presync postsync } - + rv32i[csrrwi{0-4}] = { alu rd csr_read rs1 csr_write csr_imm lor presync postsync } # optimize csr write only - pipelined diff --git a/design/dma_ctrl.sv b/design/dma_ctrl.sv index cd42233..64cc827 100644 --- a/design/dma_ctrl.sv +++ b/design/dma_ctrl.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,7 +17,7 @@ // $Id$ // // Function: Top level SWERV core file -// Comments: +// Comments: // //******************************************************************************** @@ -28,7 +28,7 @@ module dma_ctrl ( input logic dma_bus_clk_en, // slave bus clock enable input logic clk_override, - // AXI signals + // AXI signals // AXI Write Channels input logic dma_axi_awvalid, output logic dma_axi_awready, @@ -40,12 +40,12 @@ module dma_ctrl ( input logic [1:0] dma_axi_awburst, - input logic dma_axi_wvalid, + input logic dma_axi_wvalid, output logic dma_axi_wready, input logic [63:0] dma_axi_wdata, input logic [7:0] dma_axi_wstrb, input logic dma_axi_wlast, - + output logic dma_axi_bvalid, input logic dma_axi_bready, output logic [1:0] dma_axi_bresp, @@ -55,7 +55,7 @@ module dma_ctrl ( input logic dma_axi_arvalid, output logic dma_axi_arready, input logic [`RV_DMA_BUS_TAG-1:0] dma_axi_arid, - input logic [31:0] dma_axi_araddr, + input logic [31:0] dma_axi_araddr, input logic [2:0] dma_axi_arsize, input logic [2:0] dma_axi_arprot, input logic [7:0] dma_axi_arlen, @@ -68,13 +68,13 @@ module dma_ctrl ( output logic [1:0] dma_axi_rresp, output logic dma_axi_rlast, - output logic dma_slv_algn_err, + output logic dma_slv_algn_err, // Debug signals input logic [31:0] dbg_cmd_addr, input logic [31:0] dbg_cmd_wrdata, - input logic dbg_cmd_valid, + input logic dbg_cmd_valid, input logic dbg_cmd_write, // 1: write command, 0: read_command - input logic [1:0] dbg_cmd_type, // 0:gpr 1:csr 2: memory + input logic [1:0] dbg_cmd_type, // 0:gpr 1:csr 2: memory input logic [1:0] dbg_cmd_size, // size of the abstract mem access debug command input logic dbg_dma_bubble, // Debug needs a bubble to send a valid @@ -83,7 +83,7 @@ module dma_ctrl ( output logic dma_dbg_cmd_done, output logic dma_dbg_cmd_fail, output logic [31:0] dma_dbg_rddata, - + // Core side signals output logic dma_dccm_req, // DMA dccm request (only one of dccm/iccm will be set) output logic dma_iccm_req, // DMA iccm request @@ -105,15 +105,15 @@ module dma_ctrl ( input logic iccm_ready, // iccm ready to accept DMA request input logic dec_tlu_stall_dma, // stall dma accesses, tlu is attempting to enter halt/debug mode - input logic scan_mode + input logic scan_mode ); `include "global.h" - + localparam DEPTH = DMA_BUF_DEPTH; localparam DEPTH_PTR = $clog2(DEPTH); localparam NACK_COUNT = 7; - + logic [DEPTH-1:0] fifo_valid; logic [DEPTH-1:0][1:0] fifo_error; logic [DEPTH-1:0] fifo_dccm_valid; @@ -130,7 +130,7 @@ module dma_ctrl ( logic [DEPTH-1:0] fifo_dbg; logic [DEPTH-1:0][63:0] fifo_data; logic [DEPTH-1:0][DMA_BUS_TAG-1:0] fifo_tag; - + logic [DEPTH-1:0] fifo_cmd_en; logic [DEPTH-1:0] fifo_valid_en; logic [DEPTH-1:0] fifo_data_en; @@ -148,7 +148,7 @@ module dma_ctrl ( logic fifo_dbg_in; logic [31:0] fifo_addr_in; logic [2:0] fifo_sz_in; - + logic [DEPTH_PTR-1:0] RspPtr, PrevRspPtr; logic [DEPTH_PTR-1:0] WrPtr, NxtWrPtr; logic [DEPTH_PTR-1:0] RdPtr, NxtRdPtr; @@ -159,7 +159,7 @@ module dma_ctrl ( logic fifo_full, fifo_full_spec, fifo_empty; logic dma_address_error, dma_alignment_error; - logic [3:0] num_fifo_vld; + logic [3:0] num_fifo_vld; logic dma_mem_req; logic dma_addr_in_dccm; logic dma_addr_in_iccm; @@ -167,7 +167,7 @@ module dma_ctrl ( logic dma_addr_in_pic_region_nc; logic dma_addr_in_dccm_region_nc; logic dma_addr_in_iccm_region_nc; - + logic [2:0] dma_nack_count, dma_nack_count_d; logic dma_buffer_c1_clken; @@ -175,7 +175,7 @@ module dma_ctrl ( logic dma_buffer_c1_clk; logic dma_free_clk; logic dma_bus_clk; - + logic wrbuf_en, wrbuf_data_en; logic wrbuf_cmd_sent, wrbuf_rst, wrbuf_data_rst; @@ -186,7 +186,7 @@ module dma_ctrl ( logic [31:0] wrbuf_addr; logic [63:0] wrbuf_data; logic [7:0] wrbuf_byteen; - + logic rdbuf_en; logic rdbuf_cmd_sent, rdbuf_rst; logic rdbuf_vld; @@ -202,7 +202,7 @@ module dma_ctrl ( logic [2:0] axi_mstr_size; logic [63:0] axi_mstr_wdata; logic [7:0] axi_mstr_wstrb; - + logic axi_mstr_prty_in, axi_mstr_prty_en; logic axi_mstr_priority; logic axi_mstr_sel; @@ -213,7 +213,7 @@ module dma_ctrl ( logic [DMA_BUS_TAG-1:0] axi_slv_tag; logic [1:0] axi_slv_error; logic [63:0] axi_slv_rdata; - + logic dma_bus_clk_en_q; logic fifo_full_spec_bus; logic dbg_dma_bubble_bus; @@ -228,14 +228,14 @@ module dma_ctrl ( assign fifo_write_in = dbg_cmd_valid ? dbg_cmd_write : axi_mstr_write; assign fifo_dbg_in = dbg_cmd_valid; //assign fifo_error_in[1:0] = dccm_dma_rvalid ? {1'b0,dccm_dma_ecc_error} : iccm_dma_rvalid ? {1'b0,iccm_dma_ecc_error} : {(dma_address_error | dma_alignment_error | dma_dbg_cmd_error_in), dma_alignment_error}; - //assign fifo_data_in[63:0] = dccm_dma_rvalid ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid ? iccm_dma_rdata[63:0] : + //assign fifo_data_in[63:0] = dccm_dma_rvalid ? dccm_dma_rdata[63:0] : (iccm_dma_rvalid ? iccm_dma_rdata[63:0] : // (dbg_cmd_valid ? {2{dbg_cmd_wrdata[31:0]}} : axi_mstr_wdata[63:0])); for (genvar i=0 ;i write has higher priority assign axi_mstr_sel = (wrbuf_vld & wrbuf_data_vld & rdbuf_vld) ? axi_mstr_priority : (wrbuf_vld & wrbuf_data_vld); @@ -430,23 +430,23 @@ module dma_ctrl ( rvdff #(.WIDTH(1)) axi_slv_sentff (.din(axi_slv_sent), .dout(axi_slv_sent_q), .clk(dma_bus_clk), .*); assign axi_slv_valid = fifo_valid[RspPtr] & ~fifo_rsp_done[RspPtr] & ~fifo_dbg[RspPtr] & (fifo_write[RspPtr] | fifo_data_bus_valid[RspPtr] | fifo_error_bus[RspPtr]); - assign axi_slv_tag[DMA_BUS_TAG-1:0] = fifo_tag[RspPtr]; + assign axi_slv_tag[DMA_BUS_TAG-1:0] = fifo_tag[RspPtr]; assign axi_slv_rdata[63:0] = (|fifo_error[RspPtr]) ? {32'b0,fifo_addr[RspPtr]} : fifo_data[RspPtr]; assign axi_slv_write = fifo_write[RspPtr]; assign axi_slv_error[1:0] = fifo_error[RspPtr][0] ? 2'b10 : (fifo_error[RspPtr][1] ? 2'b11 : 2'b0); - - + + // AXI response channel signals assign dma_axi_bvalid = axi_slv_valid & axi_slv_write; assign dma_axi_bresp[1:0] = axi_slv_error[1:0]; assign dma_axi_bid[DMA_BUS_TAG-1:0] = axi_slv_tag[DMA_BUS_TAG-1:0]; - + assign dma_axi_rvalid = axi_slv_valid & ~axi_slv_write; - assign dma_axi_rresp[1:0] = axi_slv_error; + assign dma_axi_rresp[1:0] = axi_slv_error; assign dma_axi_rid[DMA_BUS_TAG-1:0] = axi_slv_tag[DMA_BUS_TAG-1:0]; assign dma_axi_rdata[63:0] = axi_slv_rdata[63:0]; assign dma_axi_rlast = 1'b1; - + assign axi_slv_sent = (dma_axi_bvalid & dma_axi_bready) | (dma_axi_rvalid & dma_axi_rready); assign dma_slv_algn_err = fifo_error[RspPtr][1]; `ifdef ASSERT_ON @@ -463,9 +463,9 @@ module dma_ctrl ( ((dma_axi_awsize[2:0] == 3'h2) & (dma_axi_awaddr[1:0] == 2'b0)) | ((dma_axi_awsize[2:0] == 3'h3) & (dma_axi_awaddr[2:0] == 3'b0))); endproperty - // assert_dma_write_trxn_aligned: assert property (dma_axi_write_trxn_aligned) else + // assert_dma_write_trxn_aligned: assert property (dma_axi_write_trxn_aligned) else // $display("Assertion dma_axi_write_trxn_aligned failed: dma_axi_awvalid=1'b%b, dma_axi_awsize=3'h%h, dma_axi_awaddr=32'h%h",dma_axi_awvalid, dma_axi_awsize[2:0], dma_axi_awaddr[31:0]); - + // Assertion to check AXI read address is aligned to size property dma_axi_read_trxn_aligned; @(posedge dma_bus_clk) dma_axi_arvalid |-> ((dma_axi_arsize[2:0] == 3'h0) | @@ -473,37 +473,37 @@ module dma_ctrl ( ((dma_axi_arsize[2:0] == 3'h2) & (dma_axi_araddr[1:0] == 2'b0)) | ((dma_axi_arsize[2:0] == 3'h3) & (dma_axi_araddr[2:0] == 3'b0))); endproperty - // assert_dma_read_trxn_aligned: assert property (dma_axi_read_trxn_aligned) else + // assert_dma_read_trxn_aligned: assert property (dma_axi_read_trxn_aligned) else // $display("Assertion dma_axi_read_trxn_aligned failed: dma_axi_arvalid=1'b%b, dma_axi_arsize=3'h%h, dma_axi_araddr=32'h%h",dma_axi_arvalid, dma_axi_arsize[2:0], dma_axi_araddr[31:0]); - + // Assertion to check write size is 8 byte or less property dma_axi_awsize_check; @(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_awvalid & dma_axi_awready) |-> (dma_axi_awsize[2] == 1'b0); endproperty assert_dma_axi_awsize_check: assert property (dma_axi_awsize_check) else $display("DMA AXI awsize is illegal. Size greater than 8B not supported"); - + // Assertion to check there are no burst commands property dma_axi_awlen_check; @(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_awvalid & dma_axi_awready) |-> (dma_axi_awlen[7:0] == 8'b0); endproperty assert_dma_axi_awlen_check: assert property (dma_axi_awlen_check) else $display("DMA AXI awlen is illegal. Length greater than 0 not supported"); - + // Assertion to check write size is 8 byte or less property dma_axi_arsize_check; @(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_arvalid & dma_axi_arready) |-> (dma_axi_arsize[2] == 1'b0); endproperty assert_dma_axi_arsize_check: assert property (dma_axi_arsize_check) else $display("DMA AXI arsize is illegal, Size bigger than 8B not supported"); - + // Assertion to check there are no burst commands property dma_axi_arlen_check; @(posedge dma_bus_clk) disable iff(~rst_l) (dma_axi_arvalid & dma_axi_arready) |-> (dma_axi_arlen[7:0] == 8'b0); endproperty assert_dma_axi_arlen_check: assert property (dma_axi_arlen_check) else $display("DMA AXI arlen greater than 0 not supported."); - + // Assertion to check cmd valid stays stable during entire bus clock property dma_axi_awvalid_stable; @(posedge clk) disable iff(~rst_l) (dma_axi_awvalid != $past(dma_axi_awvalid)) |-> $past(dma_bus_clk_en); @@ -658,6 +658,6 @@ module dma_ctrl ( assert_dma_axi_rid_stable: assert property (dma_axi_rid_stable) else $display("DMA AXI bid changed in middle of bus clock"); -`endif - +`endif + endmodule // dma_ctrl diff --git a/design/dmi/dmi_jtag_to_core_sync.v b/design/dmi/dmi_jtag_to_core_sync.v index 2e8227f..6ba6de7 100644 --- a/design/dmi/dmi_jtag_to_core_sync.v +++ b/design/dmi/dmi_jtag_to_core_sync.v @@ -1,229 +1,229 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2019 Western Digital Corporation or its affiliates. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//------------------------------------------------------------------------------------ -// -// Copyright Western Digital, 2019 -// Owner : Anusha Narayanamoorthy -// Description: -// This module Synchronizes the signals between JTAG (TCK) and -// processor (Core_clk) -// -//------------------------------------------------------------------------------------- - -module dmi_jtag_to_core_sync ( - // JTAG signals - input trst_n, // JTAG clock - input dmireset, // dmi_reset to clear sticky bits - input tck, // JTAG reset - input [31:0] j_wr_data, // 32 bit Write data - input [31:0] j_wr_addr, // 32 bit Write address - input wr_intf, // 1 bit Write interface bit - input wr_enab, // 1 bit Write enable - - output reg [31:0] j_rd_data, // 32 bit Read data in JTAG clock - output [1:0] opcod, // 2 bit opcode - - // Processor Signals - input core_rst_n, // Core clock - input core_clk, // Core reset - input [31:0] c_rd_data, // 32 bit Read data from Processor - input c_rd_ack, // Acknowledgement signal from Processor - - output reg [31:0] c_wr_data, // 32 bit Write data to Processor - output reg [31:0] c_wr_addr, // 32 bit Write address to Processor - output reg_en, // 1 bit Write interface bit to Processor - output reg_wr_en // 1 bit Write enable to Processor -); - - parameter IDLE = 2'b0; - parameter FAIL = 2'b10; - parameter TRANS = 2'b11; - - //Internal Signal Declaration -// reg status; - reg d_reg_en; - reg [1:0] sig_opcod; - reg [1:0] state; - reg [1:0] n_state; - reg [1:0] sts_opc; - reg [1:0] reg_opcod; - - - wire c_rd_en; - wire c_wr_en; - wire j_wr_en, j_rd_en, reg_en_sig, j_status; - - - //Assign statements - assign j_wr_en = (wr_intf & wr_enab); - - assign j_rd_en = (wr_intf & (!wr_enab)); - - assign reg_en_sig = c_wr_en || c_rd_en; - - assign reg_en = reg_en_sig; - - assign reg_wr_en = c_wr_en; - - assign opcod = reg_opcod; - - //assign status = d_reg_en && (!c_rd_ack); - - //Sync rd_en to core clock - toggle_sync sync_rd_en( - .src_rst_n(trst_n), // Source domain reset - .src_clk(tck), // Source clock - .dst_clk(core_clk), // Destination clock - .dst_rst_n(core_rst_n), // Destination reset - .src_enb(j_rd_en), // Enable signal in Source clock domain - .dst_enb(c_rd_en) // Enable signal in destination clock domain -); - - - - //Sync wr_en to core clock - toggle_sync sync_wr_enb( - .src_rst_n(trst_n), // Source domain reset - .src_clk(tck), // Source clock - .dst_clk(core_clk), // Destination clock - .dst_rst_n(core_rst_n), // Destination reset - .src_enb(j_wr_en), // Enable signal in Source clock domain - .dst_enb(c_wr_en) // Enable signal in destination clock domain -); - - - // Storing wr_data when wr_enable is available - always @ (posedge tck or negedge trst_n) - if(!trst_n) - c_wr_data <= 32'b0; - else if (wr_enab) - c_wr_data <= j_wr_data; - - // Storing wr_addr when wr_enab is available - always @ (posedge tck or negedge trst_n) - if(!trst_n) - c_wr_addr <= 32'b0; - else if (wr_intf) - c_wr_addr <= j_wr_addr; - - - // Storing read data when rd_ack is available - always @ (posedge core_clk or negedge core_rst_n) - if(!core_rst_n) - j_rd_data <= 32'b0; - else if(c_rd_ack) - j_rd_data <= c_rd_data; - - - // Delay assignment of Reg_en - always @ (posedge core_clk or negedge core_rst_n) - if(!core_rst_n) - d_reg_en <= 1'b0; - else - d_reg_en <= reg_en_sig; - - - // Sts opcode assignment in core clock domain to sample in tck - always @ (posedge core_clk or negedge core_rst_n) - if(!core_rst_n) - sts_opc <= 2'b0; - else if(d_reg_en && (!c_rd_ack)) - sts_opc <= 2'b10; - else if(reg_en_sig) - sts_opc <= 2'b0; - - - //Sync status to tck - toggle_sync sync_status( - .src_rst_n(core_rst_n), // Source domain reset - .src_clk(core_clk), // Source clock - .dst_clk(tck), // Destination clock - .dst_rst_n(trst_n), // Destination reset - .src_enb(d_reg_en), // Enable signal in Source clock domain - .dst_enb(j_status) // Enable signal in destination clock domain -); - - - - // State assignment for opcode assignment - always @ (posedge tck or negedge trst_n) - if(!trst_n) - state <= IDLE; - else - state <= n_state; - - // Opcod assignment - always @ (posedge tck or negedge trst_n) - if(!trst_n) - reg_opcod <= 2'b0; - else - reg_opcod <= sig_opcod; - - - - // State machine for opcode assignment - always @ (*) - begin - case(state) - IDLE : begin - if(wr_intf) - begin - sig_opcod = 2'b11; - n_state = TRANS; - end - else - begin - sig_opcod = 2'b0; - n_state = IDLE; - end - end - FAIL : begin - if(dmireset) - begin - sig_opcod = 2'b0; - n_state = IDLE; - end - else - begin - sig_opcod = 2'b10; - n_state = FAIL; - end - end - TRANS : begin - if(j_status && (sts_opc == 2'b10)) - begin - sig_opcod = 2'b10; - n_state = FAIL; - end - else if (j_status && (sts_opc == 2'b00)) - begin - sig_opcod = 2'b00; - n_state = IDLE; - end - else - begin - sig_opcod = 2'b11; - n_state = TRANS; - end - end - default : begin - sig_opcod = opcod; - n_state = state; - end - endcase - end - - -endmodule +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//------------------------------------------------------------------------------------ +// +// Copyright Western Digital, 2019 +// Owner : Anusha Narayanamoorthy +// Description: +// This module Synchronizes the signals between JTAG (TCK) and +// processor (Core_clk) +// +//------------------------------------------------------------------------------------- + +module dmi_jtag_to_core_sync ( + // JTAG signals + input trst_n, // JTAG clock + input dmireset, // dmi_reset to clear sticky bits + input tck, // JTAG reset + input [31:0] j_wr_data, // 32 bit Write data + input [31:0] j_wr_addr, // 32 bit Write address + input wr_intf, // 1 bit Write interface bit + input wr_enab, // 1 bit Write enable + + output reg [31:0] j_rd_data, // 32 bit Read data in JTAG clock + output [1:0] opcod, // 2 bit opcode + + // Processor Signals + input core_rst_n, // Core clock + input core_clk, // Core reset + input [31:0] c_rd_data, // 32 bit Read data from Processor + input c_rd_ack, // Acknowledgement signal from Processor + + output reg [31:0] c_wr_data, // 32 bit Write data to Processor + output reg [31:0] c_wr_addr, // 32 bit Write address to Processor + output reg_en, // 1 bit Write interface bit to Processor + output reg_wr_en // 1 bit Write enable to Processor +); + + parameter IDLE = 2'b0; + parameter FAIL = 2'b10; + parameter TRANS = 2'b11; + + //Internal Signal Declaration +// reg status; + reg d_reg_en; + reg [1:0] sig_opcod; + reg [1:0] state; + reg [1:0] n_state; + reg [1:0] sts_opc; + reg [1:0] reg_opcod; + + + wire c_rd_en; + wire c_wr_en; + wire j_wr_en, j_rd_en, reg_en_sig, j_status; + + + //Assign statements + assign j_wr_en = (wr_intf & wr_enab); + + assign j_rd_en = (wr_intf & (!wr_enab)); + + assign reg_en_sig = c_wr_en || c_rd_en; + + assign reg_en = reg_en_sig; + + assign reg_wr_en = c_wr_en; + + assign opcod = reg_opcod; + + //assign status = d_reg_en && (!c_rd_ack); + + //Sync rd_en to core clock + toggle_sync sync_rd_en( + .src_rst_n(trst_n), // Source domain reset + .src_clk(tck), // Source clock + .dst_clk(core_clk), // Destination clock + .dst_rst_n(core_rst_n), // Destination reset + .src_enb(j_rd_en), // Enable signal in Source clock domain + .dst_enb(c_rd_en) // Enable signal in destination clock domain +); + + + + //Sync wr_en to core clock + toggle_sync sync_wr_enb( + .src_rst_n(trst_n), // Source domain reset + .src_clk(tck), // Source clock + .dst_clk(core_clk), // Destination clock + .dst_rst_n(core_rst_n), // Destination reset + .src_enb(j_wr_en), // Enable signal in Source clock domain + .dst_enb(c_wr_en) // Enable signal in destination clock domain +); + + + // Storing wr_data when wr_enable is available + always @ (posedge tck or negedge trst_n) + if(!trst_n) + c_wr_data <= 32'b0; + else if (wr_enab) + c_wr_data <= j_wr_data; + + // Storing wr_addr when wr_enab is available + always @ (posedge tck or negedge trst_n) + if(!trst_n) + c_wr_addr <= 32'b0; + else if (wr_intf) + c_wr_addr <= j_wr_addr; + + + // Storing read data when rd_ack is available + always @ (posedge core_clk or negedge core_rst_n) + if(!core_rst_n) + j_rd_data <= 32'b0; + else if(c_rd_ack) + j_rd_data <= c_rd_data; + + + // Delay assignment of Reg_en + always @ (posedge core_clk or negedge core_rst_n) + if(!core_rst_n) + d_reg_en <= 1'b0; + else + d_reg_en <= reg_en_sig; + + + // Sts opcode assignment in core clock domain to sample in tck + always @ (posedge core_clk or negedge core_rst_n) + if(!core_rst_n) + sts_opc <= 2'b0; + else if(d_reg_en && (!c_rd_ack)) + sts_opc <= 2'b10; + else if(reg_en_sig) + sts_opc <= 2'b0; + + + //Sync status to tck + toggle_sync sync_status( + .src_rst_n(core_rst_n), // Source domain reset + .src_clk(core_clk), // Source clock + .dst_clk(tck), // Destination clock + .dst_rst_n(trst_n), // Destination reset + .src_enb(d_reg_en), // Enable signal in Source clock domain + .dst_enb(j_status) // Enable signal in destination clock domain +); + + + + // State assignment for opcode assignment + always @ (posedge tck or negedge trst_n) + if(!trst_n) + state <= IDLE; + else + state <= n_state; + + // Opcod assignment + always @ (posedge tck or negedge trst_n) + if(!trst_n) + reg_opcod <= 2'b0; + else + reg_opcod <= sig_opcod; + + + + // State machine for opcode assignment + always @ (*) + begin + case(state) + IDLE : begin + if(wr_intf) + begin + sig_opcod = 2'b11; + n_state = TRANS; + end + else + begin + sig_opcod = 2'b0; + n_state = IDLE; + end + end + FAIL : begin + if(dmireset) + begin + sig_opcod = 2'b0; + n_state = IDLE; + end + else + begin + sig_opcod = 2'b10; + n_state = FAIL; + end + end + TRANS : begin + if(j_status && (sts_opc == 2'b10)) + begin + sig_opcod = 2'b10; + n_state = FAIL; + end + else if (j_status && (sts_opc == 2'b00)) + begin + sig_opcod = 2'b00; + n_state = IDLE; + end + else + begin + sig_opcod = 2'b11; + n_state = TRANS; + end + end + default : begin + sig_opcod = opcod; + n_state = state; + end + endcase + end + + +endmodule diff --git a/design/dmi/dmi_wrapper.v b/design/dmi/dmi_wrapper.v index 7d5df52..39f5298 100644 --- a/design/dmi/dmi_wrapper.v +++ b/design/dmi/dmi_wrapper.v @@ -1,120 +1,120 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2019 Western Digital Corporation or its affiliates. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//------------------------------------------------------------------------------------ -// -// Copyright Western Digital, 2019 -// Owner : Anusha Narayanamoorthy -// Description: -// Wrapper module for JTAG_TAP and DMI synchronizer -// -//------------------------------------------------------------------------------------- - -module dmi_wrapper( - // JTAG signals - input trst_n, // JTAG clock - input tck, // JTAG reset - input tms, // Test mode select - input tdi, // Test Data Input - output tdo, // Test Data Output - output tdoEnable, // Test Data Output enable - - // Processor Signals - input scan_mode, - input core_rst_n, // Core clock - input core_clk, // Core reset - input [31:0] rd_data, // 32 bit Read data from Processor - input reg_ack, // Acknowledgement signal from Processor - output [31:0] reg_wr_data, // 32 bit Write data to Processor - output [31:0] reg_wr_addr, // 32 bit Write address to Processor - output reg_en, // 1 bit Write interface bit to Processor - output reg_wr_en, // 1 bit Write enable to Processor - output dmi_hard_reset -); - - - - parameter DEVICE_ID_VAL = 32'b00000000000000000000000000000001; - - - //Wire Declaration - wire [31:0] j_wr_data; - wire [31:0] j_wr_addr; - wire wr_intf; - wire wr_enab; - wire [31:0] j_rd_data; - wire [1:0] sts_opcod; - wire dmireset; - - wire [31:0] j_wr_data_OS, j_wr_addr_OS; - wire tdo_OS, tdoEnable_OS, wr_intf_OS, wr_enab_OS, dmireset_OS, dmi_hard_reset_OS; - - assign j_wr_data[31:0] = j_wr_data_OS; - assign j_wr_addr[31:0] = j_wr_addr_OS; - assign tdo = tdo_OS; - assign tdoEnable = tdoEnable_OS; - assign wr_intf = wr_intf_OS; - assign wr_enab = wr_enab_OS; - assign dmireset = dmireset_OS; - assign dmi_hard_reset = dmi_hard_reset_OS; - - rvjtag_tap #(.DEVICE_ID_VAL(DEVICE_ID_VAL)) i_rvjtag_tap( - .scan_mode(scan_mode), - .trst(trst_n), // dedicated JTAG TRST (active low) pad signal or asynchronous active low power on reset - .tck(tck), // dedicated JTAG TCK pad signal - .tms(tms), // dedicated JTAG TMS pad signal - .tdi(tdi), // dedicated JTAG TDI pad signal - .tdo(tdo_OS), // dedicated JTAG TDO pad signal - .tdoEnable(tdoEnable_OS), // enable for TDO pad - .wr_data(j_wr_data_OS), // 32 bit Write data - .wr_addr(j_wr_addr_OS), // 32 bit Write address - .wr_intf(wr_intf_OS), // 1 bit Write interface bit - .wr_enab(wr_enab_OS), // 1 bit Write enable - .rd_data(j_rd_data), // 32 bit Read data - .rd_status(sts_opcod), // 1 bit Read ack - .idle(3'h0), - .dmi_stat(sts_opcod), - .abits(6'h20), - .version(4'h1), - .dmi_hard_reset(dmi_hard_reset_OS), - .dmi_reset(dmireset_OS) -); - - - // dmi_jtag_to_core_sync instantiation - dmi_jtag_to_core_sync i_dmi_jtag_to_core_sync( - .trst_n(trst_n), - .dmireset(dmireset), - .tck(tck), - .wr_intf(wr_intf), // 1 bit Write interface bit - .wr_enab(wr_enab), // 1 bit Write enable - .j_wr_data(j_wr_data), // 32 bit Write data - .j_wr_addr(j_wr_addr), // 32 bit Write address - - .j_rd_data(j_rd_data), // 32 bit Read data - .opcod(sts_opcod), // Read ack synhcronized to TCK - - .core_rst_n(core_rst_n), - .core_clk(core_clk), - - .c_rd_data(rd_data), // 32 bit Read data - .c_rd_ack(reg_ack), // Read ack from core clock - - .c_wr_data(reg_wr_data), // 32 bit Write data - .c_wr_addr(reg_wr_addr), // 32 bit Write address - .reg_en(reg_en), // 1 bit Write interface bit - .reg_wr_en(reg_wr_en) // 1 bit Write enable - ); - -endmodule +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//------------------------------------------------------------------------------------ +// +// Copyright Western Digital, 2019 +// Owner : Anusha Narayanamoorthy +// Description: +// Wrapper module for JTAG_TAP and DMI synchronizer +// +//------------------------------------------------------------------------------------- + +module dmi_wrapper( + // JTAG signals + input trst_n, // JTAG clock + input tck, // JTAG reset + input tms, // Test mode select + input tdi, // Test Data Input + output tdo, // Test Data Output + output tdoEnable, // Test Data Output enable + + // Processor Signals + input scan_mode, + input core_rst_n, // Core clock + input core_clk, // Core reset + input [31:0] rd_data, // 32 bit Read data from Processor + input reg_ack, // Acknowledgement signal from Processor + output [31:0] reg_wr_data, // 32 bit Write data to Processor + output [31:0] reg_wr_addr, // 32 bit Write address to Processor + output reg_en, // 1 bit Write interface bit to Processor + output reg_wr_en, // 1 bit Write enable to Processor + output dmi_hard_reset +); + + + + parameter DEVICE_ID_VAL = 32'b00000000000000000000000000000001; + + + //Wire Declaration + wire [31:0] j_wr_data; + wire [31:0] j_wr_addr; + wire wr_intf; + wire wr_enab; + wire [31:0] j_rd_data; + wire [1:0] sts_opcod; + wire dmireset; + + wire [31:0] j_wr_data_OS, j_wr_addr_OS; + wire tdo_OS, tdoEnable_OS, wr_intf_OS, wr_enab_OS, dmireset_OS, dmi_hard_reset_OS; + + assign j_wr_data[31:0] = j_wr_data_OS; + assign j_wr_addr[31:0] = j_wr_addr_OS; + assign tdo = tdo_OS; + assign tdoEnable = tdoEnable_OS; + assign wr_intf = wr_intf_OS; + assign wr_enab = wr_enab_OS; + assign dmireset = dmireset_OS; + assign dmi_hard_reset = dmi_hard_reset_OS; + + rvjtag_tap #(.DEVICE_ID_VAL(DEVICE_ID_VAL)) i_rvjtag_tap( + .scan_mode(scan_mode), + .trst(trst_n), // dedicated JTAG TRST (active low) pad signal or asynchronous active low power on reset + .tck(tck), // dedicated JTAG TCK pad signal + .tms(tms), // dedicated JTAG TMS pad signal + .tdi(tdi), // dedicated JTAG TDI pad signal + .tdo(tdo_OS), // dedicated JTAG TDO pad signal + .tdoEnable(tdoEnable_OS), // enable for TDO pad + .wr_data(j_wr_data_OS), // 32 bit Write data + .wr_addr(j_wr_addr_OS), // 32 bit Write address + .wr_intf(wr_intf_OS), // 1 bit Write interface bit + .wr_enab(wr_enab_OS), // 1 bit Write enable + .rd_data(j_rd_data), // 32 bit Read data + .rd_status(sts_opcod), // 1 bit Read ack + .idle(3'h0), + .dmi_stat(sts_opcod), + .abits(6'h20), + .version(4'h1), + .dmi_hard_reset(dmi_hard_reset_OS), + .dmi_reset(dmireset_OS) +); + + + // dmi_jtag_to_core_sync instantiation + dmi_jtag_to_core_sync i_dmi_jtag_to_core_sync( + .trst_n(trst_n), + .dmireset(dmireset), + .tck(tck), + .wr_intf(wr_intf), // 1 bit Write interface bit + .wr_enab(wr_enab), // 1 bit Write enable + .j_wr_data(j_wr_data), // 32 bit Write data + .j_wr_addr(j_wr_addr), // 32 bit Write address + + .j_rd_data(j_rd_data), // 32 bit Read data + .opcod(sts_opcod), // Read ack synhcronized to TCK + + .core_rst_n(core_rst_n), + .core_clk(core_clk), + + .c_rd_data(rd_data), // 32 bit Read data + .c_rd_ack(reg_ack), // Read ack from core clock + + .c_wr_data(reg_wr_data), // 32 bit Write data + .c_wr_addr(reg_wr_addr), // 32 bit Write address + .reg_en(reg_en), // 1 bit Write interface bit + .reg_wr_en(reg_wr_en) // 1 bit Write enable + ); + +endmodule diff --git a/design/dmi/double_flop_sync.v b/design/dmi/double_flop_sync.v index 0cb8878..025dbee 100644 --- a/design/dmi/double_flop_sync.v +++ b/design/dmi/double_flop_sync.v @@ -1,52 +1,52 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2019 Western Digital Corporation or its affiliates. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//------------------------------------------------------------------------------------ -// -// Copyright Western Digital, 2019 -// Owner : Anusha Narayanamoorthy -// Description: -// Double flop synchronizer -// -//------------------------------------------------------------------------------------- - - -module double_flop_sync ( - input clk, // Input clock - input rst_n, // Input reset - input inp, // Input singal - output reg op // Double flopped output signal -); - -reg d_inp; - - - // Flop the enable signal in the Destination clock domain - always @ (posedge clk or negedge rst_n) - if(!rst_n) - d_inp <= 1'b0; - else - d_inp <= inp; - - - - // Double flop the enable signal in the Destination clock domain - always @ (posedge clk or negedge rst_n) - if(!rst_n) - op <= 1'b0; - else - op <= d_inp; - - -endmodule +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//------------------------------------------------------------------------------------ +// +// Copyright Western Digital, 2019 +// Owner : Anusha Narayanamoorthy +// Description: +// Double flop synchronizer +// +//------------------------------------------------------------------------------------- + + +module double_flop_sync ( + input clk, // Input clock + input rst_n, // Input reset + input inp, // Input singal + output reg op // Double flopped output signal +); + +reg d_inp; + + + // Flop the enable signal in the Destination clock domain + always @ (posedge clk or negedge rst_n) + if(!rst_n) + d_inp <= 1'b0; + else + d_inp <= inp; + + + + // Double flop the enable signal in the Destination clock domain + always @ (posedge clk or negedge rst_n) + if(!rst_n) + op <= 1'b0; + else + op <= d_inp; + + +endmodule diff --git a/design/dmi/rvjtag_tap.sv b/design/dmi/rvjtag_tap.sv index 89b76fb..26f87dc 100644 --- a/design/dmi/rvjtag_tap.sv +++ b/design/dmi/rvjtag_tap.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -60,21 +60,21 @@ input [1:0] dmi_stat; input [5:0] abits; input [3:0] version; - + /* -- revisionCode : 4'h0; -- manufacturersIdCode : 11'h000; -- deviceIdCode : 16'h0001; -- order MSB .. LSB -> [4 bit version or revision] [16 bit part number] [11 bit manufacturer id] [value of 1'b1 in LSB] */ -// Device ID +// Device ID parameter DEVICE_ID_VAL = 32'b1; localparam USER_DR_LENGTH = 66; -reg tdo; +reg tdo; reg dmi_reset; reg dmi_hard_reset; - + reg [USER_DR_LENGTH-1:0] sr, nsr, dr; /////////////////////////////////////////////////////// @@ -82,13 +82,13 @@ reg [USER_DR_LENGTH-1:0] sr, nsr, dr; /////////////////////////////////////////////////////// logic[3:0] state, nstate; logic [4:0] ir; -wire jtag_reset; -wire shift_dr; -wire pause_dr; -wire update_dr; +wire jtag_reset; +wire shift_dr; +wire pause_dr; +wire update_dr; wire capture_dr; -wire shift_ir; -wire pause_ir ; +wire shift_ir; +wire pause_ir ; wire update_ir ; wire capture_ir; wire[1:0] dr_en; @@ -115,7 +115,7 @@ always_comb begin nstate = state; case(state) TEST_LOGIC_RESET_STATE: nstate = tms ? TEST_LOGIC_RESET_STATE : RUN_TEST_IDLE_STATE; - RUN_TEST_IDLE_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE; + RUN_TEST_IDLE_STATE: nstate = tms ? SELECT_DR_SCAN_STATE : RUN_TEST_IDLE_STATE; SELECT_DR_SCAN_STATE: nstate = tms ? SELECT_IR_SCAN_STATE : CAPTURE_DR_STATE; CAPTURE_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE; SHIFT_DR_STATE: nstate = tms ? EXIT1_DR_STATE : SHIFT_DR_STATE; @@ -167,7 +167,7 @@ end assign devid_sel = ir == 5'b00001; assign dr_en[0] = ir == 5'b10000; assign dr_en[1] = ir == 5'b10001; - + /////////////////////////////////////////////////////// // Shift register /////////////////////////////////////////////////////// @@ -213,11 +213,11 @@ always @ (posedge tck or negedge trst) begin if(!trst) begin dmi_hard_reset <= 1'b0; dmi_reset <= 1'b0; - end + end else if (update_dr & dr_en[0]) begin dmi_hard_reset <= sr[17]; dmi_reset <= sr[16]; - end + end else begin dmi_hard_reset <= 1'b0; dmi_reset <= 1'b0; diff --git a/design/dmi/toggle_sync.v b/design/dmi/toggle_sync.v index 99ebeb9..4d10cfc 100644 --- a/design/dmi/toggle_sync.v +++ b/design/dmi/toggle_sync.v @@ -1,69 +1,69 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2019 Western Digital Corporation or its affiliates. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License -// //------------------------------------------------------------------------------------ -// -// Copyright Western Digital, 2019 -// Owner : Anusha Narayanamoorthy -// Description: -// Toggle synchronizer -// -//------------------------------------------------------------------------------------- - -module toggle_sync( - input src_rst_n, // Source reset - input src_clk, // Source clock - input dst_clk, // Destination clock - input dst_rst_n, // Destination reset - input src_enb, // Enable signal in Source clock domain - output dst_enb // Enable signal in destination clock domain -); - - -// Reg declaration -reg tgle_s_en; -reg d3_en; - -// Wire Declararation -wire dble_flp_en; - - - // Latching the enable signal in Source clock domain - always @ (posedge src_clk or negedge src_rst_n) - if(!src_rst_n) - tgle_s_en <= 1'b0; - else if (src_enb) - tgle_s_en <= ~tgle_s_en; - - // Instantiation of Double flop synchronizer - double_flop_sync i_double_flop_sync( - .clk(dst_clk), - .rst_n(dst_rst_n), - .inp(tgle_s_en), - .op(dble_flp_en) -); - - - - // Triple flop the enable signal in the Destination clock domain - always @ (posedge dst_clk or negedge dst_rst_n) - if(!dst_rst_n) - d3_en <= 1'b0; - else - d3_en <= dble_flp_en; - - - assign dst_enb = dble_flp_en ^ d3_en; - -endmodule +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License +// //------------------------------------------------------------------------------------ +// +// Copyright Western Digital, 2019 +// Owner : Anusha Narayanamoorthy +// Description: +// Toggle synchronizer +// +//------------------------------------------------------------------------------------- + +module toggle_sync( + input src_rst_n, // Source reset + input src_clk, // Source clock + input dst_clk, // Destination clock + input dst_rst_n, // Destination reset + input src_enb, // Enable signal in Source clock domain + output dst_enb // Enable signal in destination clock domain +); + + +// Reg declaration +reg tgle_s_en; +reg d3_en; + +// Wire Declararation +wire dble_flp_en; + + + // Latching the enable signal in Source clock domain + always @ (posedge src_clk or negedge src_rst_n) + if(!src_rst_n) + tgle_s_en <= 1'b0; + else if (src_enb) + tgle_s_en <= ~tgle_s_en; + + // Instantiation of Double flop synchronizer + double_flop_sync i_double_flop_sync( + .clk(dst_clk), + .rst_n(dst_rst_n), + .inp(tgle_s_en), + .op(dble_flp_en) +); + + + + // Triple flop the enable signal in the Destination clock domain + always @ (posedge dst_clk or negedge dst_rst_n) + if(!dst_rst_n) + d3_en <= 1'b0; + else + d3_en <= dble_flp_en; + + + assign dst_enb = dble_flp_en ^ d3_en; + +endmodule diff --git a/design/exu/exu.sv b/design/exu/exu.sv index ff3b57d..37d7938 100644 --- a/design/exu/exu.sv +++ b/design/exu/exu.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -176,7 +176,7 @@ module exu output logic [`RV_BHT_GHR_RANGE] exu_i0_br_fghr_e4, // to DEC I0 branch fghr output logic exu_i0_br_ret_e4, // to DEC I0 branch return output logic exu_i0_br_call_e4, // to DEC I0 branch call - + output logic [1:0] exu_i1_br_hist_e4, // to DEC I1 branch history output logic [1:0] exu_i1_br_bank_e4, // to DEC I1 branch bank output logic exu_i1_br_error_e4, // to DEC I1 branch error @@ -292,15 +292,15 @@ module exu ({32{ dec_i1_rs1_bypass_en_d}} & i1_rs1_bypass_data_d[31:0]); assign i1_rs2_d[31:0] = ({32{~dec_i1_rs2_bypass_en_d}} & gpr_i1_rs2_d[31:0]) | - ({32{~dec_i1_rs2_bypass_en_d}} & dec_i1_immed_d[31:0]) | + ({32{~dec_i1_rs2_bypass_en_d}} & dec_i1_immed_d[31:0]) | ({32{ dec_i1_rs2_bypass_en_d}} & i1_rs2_bypass_data_d[31:0]); - assign exu_lsu_rs1_d[31:0] = ({32{ ~dec_i0_rs1_bypass_en_d & dec_i0_lsu_d }} & gpr_i0_rs1_d[31:0] ) | + assign exu_lsu_rs1_d[31:0] = ({32{ ~dec_i0_rs1_bypass_en_d & dec_i0_lsu_d }} & gpr_i0_rs1_d[31:0] ) | ({32{ ~dec_i1_rs1_bypass_en_d & ~dec_i0_lsu_d & dec_i1_lsu_d}} & gpr_i1_rs1_d[31:0] ) | ({32{ dec_i0_rs1_bypass_en_d & dec_i0_lsu_d }} & i0_rs1_bypass_data_d[31:0]) | ({32{ dec_i1_rs1_bypass_en_d & ~dec_i0_lsu_d & dec_i1_lsu_d}} & i1_rs1_bypass_data_d[31:0]); - assign exu_lsu_rs2_d[31:0] = ({32{ ~dec_i0_rs2_bypass_en_d & dec_i0_lsu_d }} & gpr_i0_rs2_d[31:0] ) | + assign exu_lsu_rs2_d[31:0] = ({32{ ~dec_i0_rs2_bypass_en_d & dec_i0_lsu_d }} & gpr_i0_rs2_d[31:0] ) | ({32{ ~dec_i1_rs2_bypass_en_d & ~dec_i0_lsu_d & dec_i1_lsu_d}} & gpr_i1_rs2_d[31:0] ) | ({32{ dec_i0_rs2_bypass_en_d & dec_i0_lsu_d }} & i0_rs2_bypass_data_d[31:0]) | ({32{ dec_i1_rs2_bypass_en_d & ~dec_i0_lsu_d & dec_i1_lsu_d}} & i1_rs2_bypass_data_d[31:0]); @@ -384,7 +384,7 @@ module exu i1_predict_newp_d.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = i1_predict_p_d.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; i1_predict_newp_d.bank[1:0] = i1_predict_p_d.bank[1:0]; - end + end predict_pkt_t i0_predict_p_e1, i0_predict_p_e4; @@ -392,7 +392,7 @@ module exu assign exu_pmu_i0_br_misp = i0_predict_p_e4.misp; assign exu_pmu_i0_br_ataken = i0_predict_p_e4.ataken; - assign exu_pmu_i0_pc4 = i0_predict_p_e4.pc4 | exu_div_finish; // divides are always 4B + assign exu_pmu_i0_pc4 = i0_predict_p_e4.pc4 | exu_div_finish; // divides are always 4B assign exu_pmu_i1_br_misp = i1_predict_p_e4.misp; assign exu_pmu_i1_br_ataken = i1_predict_p_e4.ataken; assign exu_pmu_i1_pc4 = i1_predict_p_e4.pc4; @@ -473,19 +473,19 @@ module exu rvdffe #(76) i0_src_e1_ff (.*, .en(i0_e1_data_en), - .din( {i0_rs1_d[31:0], i0_rs2_d[31:0], dec_i0_br_immed_d[12:1]}), + .din( {i0_rs1_d[31:0], i0_rs2_d[31:0], dec_i0_br_immed_d[12:1]}), .dout({i0_rs1_e1[31:0], i0_rs2_e1[31:0], i0_br_immed_e1[12:1]}) ); - rvdffe #(76) i0_src_e2_ff (.*, + rvdffe #(76) i0_src_e2_ff (.*, .en(i0_e2_data_en), - .din( {i0_rs1_e1[31:0], i0_rs2_e1[31:0], i0_br_immed_e1[12:1]}), + .din( {i0_rs1_e1[31:0], i0_rs2_e1[31:0], i0_br_immed_e1[12:1]}), .dout({i0_rs1_e2[31:0], i0_rs2_e2[31:0], i0_br_immed_e2[12:1]}) ); - rvdffe #(76) i0_src_e3_ff (.*, + rvdffe #(76) i0_src_e3_ff (.*, .en(i0_e3_data_en), - .din( {i0_rs1_e2_final[31:0], i0_rs2_e2_final[31:0], i0_br_immed_e2[12:1]}), + .din( {i0_rs1_e2_final[31:0], i0_rs2_e2_final[31:0], i0_br_immed_e2[12:1]}), .dout({i0_rs1_e3[31:0], i0_rs2_e3[31:0], i0_br_immed_e3[12:1]}) ); @@ -493,19 +493,19 @@ module exu rvdffe #(76) i1_src_e1_ff (.*, .en(i1_e1_data_en), - .din( {i1_rs1_d[31:0], i1_rs2_d[31:0], dec_i1_br_immed_d[12:1]}), + .din( {i1_rs1_d[31:0], i1_rs2_d[31:0], dec_i1_br_immed_d[12:1]}), .dout({i1_rs1_e1[31:0], i1_rs2_e1[31:0], i1_br_immed_e1[12:1]}) ); - rvdffe #(76) i1_src_e2_ff (.*, + rvdffe #(76) i1_src_e2_ff (.*, .en(i1_e2_data_en), - .din( {i1_rs1_e1[31:0], i1_rs2_e1[31:0], i1_br_immed_e1[12:1]}), + .din( {i1_rs1_e1[31:0], i1_rs2_e1[31:0], i1_br_immed_e1[12:1]}), .dout({i1_rs1_e2[31:0], i1_rs2_e2[31:0], i1_br_immed_e2[12:1]}) ); - rvdffe #(76) i1_src_e3_ff (.*, + rvdffe #(76) i1_src_e3_ff (.*, .en(i1_e3_data_en), - .din( {i1_rs1_e2_final[31:0], i1_rs2_e2_final[31:0], i1_br_immed_e2[12:1]}), + .din( {i1_rs1_e2_final[31:0], i1_rs2_e2_final[31:0], i1_br_immed_e2[12:1]}), .dout({i1_rs1_e3[31:0], i1_rs2_e3[31:0], i1_br_immed_e3[12:1]}) ); @@ -538,7 +538,7 @@ module exu assign i1_taken_e1= (i1_ataken_e1 & dec_i1_alu_decode_e1) | (i1_predict_p_e1.hist[1] & ~dec_i1_alu_decode_e1); assign ghr_e1_ns[`RV_BHT_GHR_RANGE] = ( ({`RV_BHT_GHR_SIZE{~dec_tlu_flush_lower_wb & i0_valid_e1 & (i0_predict_p_e1.misp | ~i1_valid_e1)}} & {ghr_e1[`RV_BHT_GHR_SIZE-2:0], i0_taken_e1}) | -`ifdef RV_BHT_GHR_SIZE_2 +`ifdef RV_BHT_GHR_SIZE_2 ({`RV_BHT_GHR_SIZE{~dec_tlu_flush_lower_wb & i0_valid_e1 & ~i0_predict_p_e1.misp & i1_valid_e1}} & { i0_taken_e1, i1_taken_e1}) | `else ({`RV_BHT_GHR_SIZE{~dec_tlu_flush_lower_wb & i0_valid_e1 & ~i0_predict_p_e1.misp & i1_valid_e1}} & {ghr_e1[`RV_BHT_GHR_SIZE-3:0], i0_taken_e1, i1_taken_e1}) | @@ -556,7 +556,7 @@ module exu assign i0_valid_e4 = dec_tlu_i0_valid_e4 & ((i0_predict_p_e4.valid) | i0_predict_p_e4.misp); assign i1_pred_valid_e4 = dec_tlu_i1_valid_e4 & ((i1_predict_p_e4.valid) | i1_predict_p_e4.misp) & ~exu_i0_flush_upper_e4; assign ghr_e4_ns[`RV_BHT_GHR_RANGE] = ( ({`RV_BHT_GHR_SIZE{i0_valid_e4 & (i0_predict_p_e4.misp | ~i1_pred_valid_e4)}} & {ghr_e4[`RV_BHT_GHR_SIZE-2:0], i0_predict_p_e4.ataken}) | -`ifdef RV_BHT_GHR_SIZE_2 +`ifdef RV_BHT_GHR_SIZE_2 ({`RV_BHT_GHR_SIZE{i0_valid_e4 & ~i0_predict_p_e4.misp & i1_pred_valid_e4}} & { i0_predict_p_e4.ataken, i1_predict_p_e4.ataken}) | `else ({`RV_BHT_GHR_SIZE{i0_valid_e4 & ~i0_predict_p_e4.misp & i1_pred_valid_e4}} & {ghr_e4[`RV_BHT_GHR_SIZE-3:0], i0_predict_p_e4.ataken, i1_predict_p_e4.ataken}) | @@ -564,12 +564,12 @@ module exu ({`RV_BHT_GHR_SIZE{~i0_valid_e4 & ~i0_predict_p_e4.br_error & i1_pred_valid_e4}} & {ghr_e4[`RV_BHT_GHR_SIZE-2:0], i1_predict_p_e4.ataken}) | ({`RV_BHT_GHR_SIZE{~i0_valid_e4 & ~i1_pred_valid_e4}} & ghr_e4[`RV_BHT_GHR_RANGE]) ); - rvdff #(`RV_BHT_GHR_SIZE) e4ghrff (.*, .clk(active_clk), .din({ghr_e4_ns[`RV_BHT_GHR_RANGE]}), + rvdff #(`RV_BHT_GHR_SIZE) e4ghrff (.*, .clk(active_clk), .din({ghr_e4_ns[`RV_BHT_GHR_RANGE]}), .dout({ghr_e4[`RV_BHT_GHR_RANGE]})); - rvdff #(1) e4ghrflushff (.*, .clk(active_clk), .din({exu_flush_final}), + rvdff #(1) e4ghrflushff (.*, .clk(active_clk), .din({exu_flush_final}), .dout({exu_flush_final_f})); - // RV_NO_SECONDARY_ALU {{ + // RV_NO_SECONDARY_ALU {{ `ifdef RV_NO_SECONDARY_ALU rvdffe #($bits(predict_pkt_t)) i0_pp_e4_ff (.*, .en(i0_e4_ctl_en), .din(i0_pp_e4_in),.dout(i0_predict_p_e4) ); @@ -586,7 +586,7 @@ module exu assign exu_i1_flush_path_e4[31:1] = '0; assign i1_alu_pc_nc[31:1] = '0; assign i1_pred_correct_lower_e4 = '0; - + `else exu_alu_ctl i0_alu_e4 (.*, @@ -715,7 +715,7 @@ module exu .din({ exu_i0_flush_path_e1[31:1], exu_i0_flush_upper_e1}), - + .dout({ i0_flush_path_upper_e2[31:1], exu_i0_flush_upper_e2}) @@ -824,12 +824,12 @@ module exu assign i0_flush_path_e4_eff[31:1] = (i0_sec_decode_e4) ? exu_i0_flush_path_e4[31:1] : i0_flush_path_upper_e4[31:1]; - assign npc_e4[31:1] = (i1_valid_e4_eff) ? ((i1_pred_correct_e4_eff) ? pred_correct_npc_e4[31:1] : i1_flush_path_e4_eff[31:1]) : + assign npc_e4[31:1] = (i1_valid_e4_eff) ? ((i1_pred_correct_e4_eff) ? pred_correct_npc_e4[31:1] : i1_flush_path_e4_eff[31:1]) : ((i0_pred_correct_e4_eff) ? pred_correct_npc_e4[31:1] : i0_flush_path_e4_eff[31:1]); assign exu_npc_e4[31:1] = (div_finish_early) ? exu_i0_flush_path_e1[31:1] : - (exu_div_finish) ? div_npc[31:1] : + (exu_div_finish) ? div_npc[31:1] : npc_e4[31:1]; // remember the npc of the divide diff --git a/design/exu/exu_alu_ctl.sv b/design/exu/exu_alu_ctl.sv index e8b2680..c6b96a8 100644 --- a/design/exu/exu_alu_ctl.sv +++ b/design/exu/exu_alu_ctl.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -94,19 +94,19 @@ module exu_alu_ctl // any PC is run through here - doesn't have to be alu rvdffe #(31) pcff (.*, .en(enable), .din(pc[31:1]), .dout(pc_ff[31:1])); - rvdffe #(12) brimmff (.*, .en(enable), .din(brimm[12:1]), .dout(brimm_ff[12:1])); + rvdffe #(12) brimmff (.*, .en(enable), .din(brimm[12:1]), .dout(brimm_ff[12:1])); predict_pkt_t pp_ff; - + rvdffe #($bits(predict_pkt_t)) predictpacketff (.*, .en(enable), .din(predict_p), .dout(pp_ff) ); - - + + // immediates are just muxed into rs2 - + // add => add=1; // sub => add=1; sub=1; @@ -125,15 +125,15 @@ module exu_alu_ctl // beq => bctl=4; add; add x0, pc, sext(offset[12:1]) // bne => bctl=3; add; add x0, pc, sext(offset[12:1]) - // blt => bctl=2; add; add x0, pc, sext(offset[12:1]) - // bge => bctl=1; add; add x0, pc, sext(offset[12:1]) + // blt => bctl=2; add; add x0, pc, sext(offset[12:1]) + // bge => bctl=1; add; add x0, pc, sext(offset[12:1]) // jal => rs1=pc {pc[31:1],1'b0}, rs2=sext(offset20:1]); rd=pc+[2,4] - // jalr => rs1=rs1, rs2=sext(offset20:1]); rd=pc+[2,4] - - + // jalr => rs1=rs1, rs2=sext(offset20:1]); rd=pc+[2,4] + + assign bm[31:0] = ( ap.sub ) ? ~b_ff[31:0] : b_ff[31:0]; - + assign {cout, aout[31:0]} = {1'b0, a_ff[31:0]} + {1'b0, bm[31:0]} + {32'b0, ap.sub}; @@ -151,7 +151,7 @@ module exu_alu_ctl assign logic_sel[1] = ap.lor | ap.lxor; - + assign lout[31:0] = ( a_ff[31:0] & b_ff[31:0] & {32{logic_sel[3]}} ) | ( a_ff[31:0] & ~b_ff[31:0] & {32{logic_sel[2]}} ) | ( ~a_ff[31:0] & b_ff[31:0] & {32{logic_sel[1]}} ); @@ -163,16 +163,16 @@ module exu_alu_ctl assign sout[31:0] = ( {32{ap.sll}} & (a_ff[31:0] << b_ff[4:0]) ) | ( {32{ap.srl}} & (a_ff[31:0] >> b_ff[4:0]) ) | ( {32{ap.sra}} & ashift[31:0] ); - + assign sel_logic = |{ap.land,ap.lor,ap.lxor}; - + assign sel_shift = |{ap.sll,ap.srl,ap.sra}; assign sel_adder = (ap.add | ap.sub) & ~ap.slt; - - + + assign lt = (~ap.unsign & (neg ^ ov)) | ( ap.unsign & ~cout); @@ -181,7 +181,7 @@ module exu_alu_ctl assign slt_one = (ap.slt & lt); - + assign out[31:0] = ({32{sel_logic}} & lout[31:0]) | ({32{sel_shift}} & sout[31:0]) | ({32{sel_adder}} & aout[31:0]) | @@ -189,16 +189,16 @@ module exu_alu_ctl ({32{ap.csr_write}} & ((ap.csr_imm) ? b_ff[31:0] : a_ff[31:0])) | // csr_write: if csr_imm rs2 else rs1 ({31'b0, slt_one}); - // branch handling + // branch handling logic any_jal; - + assign any_jal = ap.jal | pp_ff.pcall | - pp_ff.pja | + pp_ff.pja | pp_ff.pret; - + assign actual_taken = (ap.beq & eq) | (ap.bne & ne) | (ap.blt & lt) | @@ -207,7 +207,7 @@ module exu_alu_ctl // 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 - + rvbradder ibradder ( .pc(pc_ff[31:1]), .offset(brimm_ff[12:1]), @@ -217,23 +217,23 @@ module exu_alu_ctl // pred_correct is for the npc logic // pred_correct indicates not to use the flush_path // for any_jal pred_correct==0 - + assign pred_correct = ((ap.predict_nt & ~actual_taken) | (ap.predict_t & actual_taken)) & ~any_jal; - + // for any_jal adder output is the flush path assign flush_path[31:1] = (any_jal) ? aout[31:1] : pcout[31:1]; // pcall and pret are included here - assign cond_mispredict = (ap.predict_t & ~actual_taken) | + assign cond_mispredict = (ap.predict_t & ~actual_taken) | (ap.predict_nt & actual_taken); // target mispredicts on ret's assign target_mispredict = pp_ff.pret & (pp_ff.prett[31:1] != aout[31:1]); - + assign flush_upper = ( ap.jal | cond_mispredict | target_mispredict) & valid_ff & ~flush & ~freeze; @@ -242,7 +242,7 @@ module exu_alu_ctl // .ilb hist[1] hist[0] taken // .ob newhist[1] newhist[0] // .type fd - // + // // 00 0 01 // 01 0 01 // 10 0 00 @@ -259,17 +259,17 @@ module exu_alu_ctl assign newhist[0] = (!pp_ff.hist[1]&!actual_taken) | (pp_ff.hist[1]&actual_taken); - + always_comb begin predict_p_ff = pp_ff; - + predict_p_ff.misp = (valid_ff) ? (cond_mispredict | target_mispredict) & ~flush : pp_ff.misp; predict_p_ff.ataken = (valid_ff) ? actual_taken : pp_ff.ataken; predict_p_ff.hist[1] = (valid_ff) ? newhist[1] : pp_ff.hist[1]; - predict_p_ff.hist[0] = (valid_ff) ? newhist[0] : pp_ff.hist[0]; - - end + predict_p_ff.hist[0] = (valid_ff) ? newhist[0] : pp_ff.hist[0]; + + end + + - - endmodule // exu_alu_ctl diff --git a/design/exu/exu_div_ctl.sv b/design/exu/exu_div_ctl.sv index 4b1c01d..0125888 100644 --- a/design/exu/exu_div_ctl.sv +++ b/design/exu/exu_div_ctl.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -26,7 +26,7 @@ module exu_div_ctl input logic [31:0] dividend, // Numerator input logic [31:0] divisor, // Denominator - + input div_pkt_t dp, // valid, sign, rem input logic flush_lower, // Flush pipeline @@ -42,7 +42,7 @@ module exu_div_ctl ); - + logic run_in, run_state; logic [5:0] count_in, count; logic [32:0] m_ff; @@ -68,7 +68,7 @@ module exu_div_ctl // short circuit logic for small numbers - + rvdff #(1) e1val_ff (.*, .clk(active_clk), .din(dp.valid & ~flush_lower_ff), .dout(valid_ff_e1)); assign valid_e1 = valid_ff_e1 & ~flush_lower_ff; @@ -80,7 +80,7 @@ module exu_div_ctl logic smallnum_case, smallnum_case_ff; logic [3:0] smallnum, smallnum_ff; - + assign smallnum_case = (q_ff[31:4] == 28'b0) & (m_ff[31:4] == 28'b0) & (m_ff[3:0] != 4'b0) & ~rem_ff & valid_e1 & ~dec_tlu_fast_div_disable; // small number divides - any 4b / 4b is done in 1 cycle (divisor != 0) @@ -90,7 +90,7 @@ module exu_div_ctl // 1) smalldiv > smalldiv.e // 2) espresso -Dso -oeqntott smalldiv.e | addassign > smalldiv - + assign smallnum[3] = (q_ff[3]&!m_ff[3]&!m_ff[2]&!m_ff[1]); assign smallnum[2] = (q_ff[3]&!m_ff[3]&!m_ff[2]&!m_ff[0]) | (q_ff[2]&!m_ff[3] @@ -128,51 +128,51 @@ module exu_div_ctl // end short circuit - - + + rvdff #(1) flush_any_ff (.*, .clk(active_clk), .din(flush_lower), .dout(flush_lower_ff)); - + assign div_stall = run_state; - - + + assign run_in = (dp.valid | run_state) & ~finish & ~flush_lower_ff; rvdff #(1) runff (.*, .clk(active_clk), .din(run_in), .dout(run_state)); assign count_in[5:0] = {6{run_state & ~finish & ~flush_lower_ff}} & (count[5:0] + 1'b1); - + rvdff #(6) countff (.*, .clk(active_clk), .din(count_in[5:0]), .dout(count[5:0])); assign finish_early = smallnum_case; - + assign finish = (smallnum_case | ((~rem_ff) ? (count[5:0] == 6'd32) : (count[5:0] == 6'd33))) & ~flush_lower & ~flush_lower_ff; assign sign_eff = ~dp.unsign & (divisor[31:0] != 32'b0); - + // divisor rvdffe #(33) mff (.*, .en(dp.valid), .din({sign_eff & divisor[31], divisor[31:0]}), .dout(m_ff[32:0])); - + // quotient assign q_in[32:0] = ({33{dp.valid}} & {1'b0,dividend[31:0]}) | ({33{~dp.valid & run_state & ~(|count[5:0])}} & {dividend_eff[31:0], ~a_in[32]}) | ({33{~dp.valid & run_state & |count[5:0]}} & {q_ff[31:0], ~a_in[32]}); - + rvdffe #(33) qff (.*, .en(dp.valid | run_state), .din(q_in[32:0]), .dout(q_ff[32:0])); rvtwoscomp #(32) dividend_c (.din(q_ff[31:0]), .dout(dividend_comp[31:0])); - + assign dividend_eff[31:0] = (sign_ff & dividend_neg_ff) ? dividend_comp[31:0] : q_ff[31:0]; - + assign m_eff[32:0] = ( add ) ? m_ff[32:0] : ~m_ff[32:0]; assign a_eff[32:0] = (rem_correct) ? a_ff[32:0] : {a_ff[31:0], q_ff[32]}; - + assign a_shift[32:0] = {33{~dp.valid & run_state}} & a_eff[32:0]; // run_state to quiet a_in for power @@ -186,7 +186,7 @@ module exu_div_ctl rvdffe #(33) aff (.*, .en(a_en), .din(a_in[32:0]), .dout(a_ff[32:0])); logic m_already_comp; - + assign m_already_comp = (divisor_neg_ff & sign_ff); // if m already complemented, then invert operation add->sub, sub->add @@ -194,20 +194,20 @@ module exu_div_ctl assign add = (a_ff[32] | rem_correct) ^ m_already_comp; assign rem_correct = (count[5:0] == 6'd33) & rem_ff & a_ff[32]; - - + + rvdffs #(4) miscf (.*, .clk(active_clk), .en(dp.valid), .din({dividend[31],divisor[31],sign_eff,dp.rem}), .dout({dividend_neg_ff,divisor_neg_ff,sign_ff,rem_ff})); rvtwoscomp #(32) q_ff_c (.din(q_ff[31:0]), .dout(q_ff_comp[31:0])); rvtwoscomp #(32) a_ff_c (.din(a_ff[31:0]), .dout(a_ff_comp[31:0])); - + assign q_ff_eff[31:0] = (sign_ff & (dividend_neg_ff ^ divisor_neg_ff)) ? q_ff_comp[31:0] : q_ff[31:0]; assign a_ff_eff[31:0] = (sign_ff & dividend_neg_ff) ? a_ff_comp[31:0] : a_ff[31:0]; assign out[31:0] = (smallnum_case_ff) ? {28'b0, smallnum_ff[3:0]} : (rem_ff) ? a_ff_eff[31:0] : q_ff_eff[31:0]; - - + + endmodule // exu_div_ctl diff --git a/design/exu/exu_mul_ctl.sv b/design/exu/exu_mul_ctl.sv index c63ea2e..96ec0ce 100644 --- a/design/exu/exu_mul_ctl.sv +++ b/design/exu/exu_mul_ctl.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -59,7 +59,7 @@ module exu_mul_ctl assign mul_c1_e2_clken = (valid_e1 | clk_override) & ~freeze; assign mul_c1_e3_clken = (valid_e2 | clk_override) & ~freeze; - // C1 - 1 clock pulse for data + // C1 - 1 clock pulse for data rvclkhdr exu_mul_c1e1_cgc (.*, .en(mul_c1_e1_clken), .l1clk(exu_mul_c1_e1_clk)); rvclkhdr exu_mul_c1e2_cgc (.*, .en(mul_c1_e2_clken), .l1clk(exu_mul_c1_e2_clk)); rvclkhdr exu_mul_c1e3_cgc (.*, .en(mul_c1_e3_clken), .l1clk(exu_mul_c1_e3_clk)); diff --git a/design/flist.vcs b/design/flist.vcs index 0923b57..5dbb3e2 100644 --- a/design/flist.vcs +++ b/design/flist.vcs @@ -1,45 +1,45 @@ -$RV_ROOT/design/swerv_wrapper.sv -$RV_ROOT/design/mem.sv -$RV_ROOT/design/pic_ctrl.sv -$RV_ROOT/design/swerv.sv -$RV_ROOT/design/dma_ctrl.sv -$RV_ROOT/design/ifu/ifu_aln_ctl.sv -$RV_ROOT/design/ifu/ifu_compress_ctl.sv -$RV_ROOT/design/ifu/ifu_ifc_ctl.sv -$RV_ROOT/design/ifu/ifu_bp_ctl.sv -$RV_ROOT/design/ifu/ifu_ic_mem.sv -$RV_ROOT/design/ifu/ifu_mem_ctl.sv -$RV_ROOT/design/ifu/ifu_iccm_mem.sv -$RV_ROOT/design/ifu/ifu.sv -$RV_ROOT/design/dec/dec_decode_ctl.sv -$RV_ROOT/design/dec/dec_gpr_ctl.sv -$RV_ROOT/design/dec/dec_ib_ctl.sv +$RV_ROOT/design/swerv_wrapper.sv +$RV_ROOT/design/mem.sv +$RV_ROOT/design/pic_ctrl.sv +$RV_ROOT/design/swerv.sv +$RV_ROOT/design/dma_ctrl.sv +$RV_ROOT/design/ifu/ifu_aln_ctl.sv +$RV_ROOT/design/ifu/ifu_compress_ctl.sv +$RV_ROOT/design/ifu/ifu_ifc_ctl.sv +$RV_ROOT/design/ifu/ifu_bp_ctl.sv +$RV_ROOT/design/ifu/ifu_ic_mem.sv +$RV_ROOT/design/ifu/ifu_mem_ctl.sv +$RV_ROOT/design/ifu/ifu_iccm_mem.sv +$RV_ROOT/design/ifu/ifu.sv +$RV_ROOT/design/dec/dec_decode_ctl.sv +$RV_ROOT/design/dec/dec_gpr_ctl.sv +$RV_ROOT/design/dec/dec_ib_ctl.sv $RV_ROOT/design/dec/dec_tlu_ctl.sv -$RV_ROOT/design/dec/dec_trigger.sv -$RV_ROOT/design/dec/dec.sv -$RV_ROOT/design/exu/exu_alu_ctl.sv -$RV_ROOT/design/exu/exu_mul_ctl.sv -$RV_ROOT/design/exu/exu_div_ctl.sv -$RV_ROOT/design/exu/exu.sv -$RV_ROOT/design/lsu/lsu.sv -$RV_ROOT/design/lsu/lsu_clkdomain.sv -$RV_ROOT/design/lsu/lsu_addrcheck.sv -$RV_ROOT/design/lsu/lsu_lsc_ctl.sv +$RV_ROOT/design/dec/dec_trigger.sv +$RV_ROOT/design/dec/dec.sv +$RV_ROOT/design/exu/exu_alu_ctl.sv +$RV_ROOT/design/exu/exu_mul_ctl.sv +$RV_ROOT/design/exu/exu_div_ctl.sv +$RV_ROOT/design/exu/exu.sv +$RV_ROOT/design/lsu/lsu.sv +$RV_ROOT/design/lsu/lsu_clkdomain.sv +$RV_ROOT/design/lsu/lsu_addrcheck.sv +$RV_ROOT/design/lsu/lsu_lsc_ctl.sv $RV_ROOT/design/lsu/lsu_stbuf.sv $RV_ROOT/design/lsu/lsu_bus_read_buffer.sv $RV_ROOT/design/lsu/lsu_bus_write_buffer.sv $RV_ROOT/design/lsu/lsu_bus_intf.sv $RV_ROOT/design/lsu/lsu_ecc.sv $RV_ROOT/design/lsu/lsu_dccm_mem.sv -$RV_ROOT/design/lsu/lsu_dccm_ctl.sv -$RV_ROOT/design/lsu/lsu_trigger.sv -$RV_ROOT/design/dbg/dbg.sv -$RV_ROOT/design/dmi/dmi_wrapper.v +$RV_ROOT/design/lsu/lsu_dccm_ctl.sv +$RV_ROOT/design/lsu/lsu_trigger.sv +$RV_ROOT/design/dbg/dbg.sv +$RV_ROOT/design/dmi/dmi_wrapper.v $RV_ROOT/design/dmi/dmi_jtag_to_core_sync.v $RV_ROOT/design/dmi/rvjtag_tap.sv $RV_ROOT/design/dmi/double_flop_sync.v $RV_ROOT/design/dmi/toggle_sync.v -$RV_ROOT/design/lib/beh_lib.sv -$RV_ROOT/design/lib/mem_lib.sv -$RV_ROOT/design/lib/ahb_to_axi4.sv -$RV_ROOT/design/lib/axi4_to_ahb.sv +$RV_ROOT/design/lib/beh_lib.sv +$RV_ROOT/design/lib/mem_lib.sv +$RV_ROOT/design/lib/ahb_to_axi4.sv +$RV_ROOT/design/lib/axi4_to_ahb.sv diff --git a/design/flist.vlog b/design/flist.vlog index 0923b57..5dbb3e2 100644 --- a/design/flist.vlog +++ b/design/flist.vlog @@ -1,45 +1,45 @@ -$RV_ROOT/design/swerv_wrapper.sv -$RV_ROOT/design/mem.sv -$RV_ROOT/design/pic_ctrl.sv -$RV_ROOT/design/swerv.sv -$RV_ROOT/design/dma_ctrl.sv -$RV_ROOT/design/ifu/ifu_aln_ctl.sv -$RV_ROOT/design/ifu/ifu_compress_ctl.sv -$RV_ROOT/design/ifu/ifu_ifc_ctl.sv -$RV_ROOT/design/ifu/ifu_bp_ctl.sv -$RV_ROOT/design/ifu/ifu_ic_mem.sv -$RV_ROOT/design/ifu/ifu_mem_ctl.sv -$RV_ROOT/design/ifu/ifu_iccm_mem.sv -$RV_ROOT/design/ifu/ifu.sv -$RV_ROOT/design/dec/dec_decode_ctl.sv -$RV_ROOT/design/dec/dec_gpr_ctl.sv -$RV_ROOT/design/dec/dec_ib_ctl.sv +$RV_ROOT/design/swerv_wrapper.sv +$RV_ROOT/design/mem.sv +$RV_ROOT/design/pic_ctrl.sv +$RV_ROOT/design/swerv.sv +$RV_ROOT/design/dma_ctrl.sv +$RV_ROOT/design/ifu/ifu_aln_ctl.sv +$RV_ROOT/design/ifu/ifu_compress_ctl.sv +$RV_ROOT/design/ifu/ifu_ifc_ctl.sv +$RV_ROOT/design/ifu/ifu_bp_ctl.sv +$RV_ROOT/design/ifu/ifu_ic_mem.sv +$RV_ROOT/design/ifu/ifu_mem_ctl.sv +$RV_ROOT/design/ifu/ifu_iccm_mem.sv +$RV_ROOT/design/ifu/ifu.sv +$RV_ROOT/design/dec/dec_decode_ctl.sv +$RV_ROOT/design/dec/dec_gpr_ctl.sv +$RV_ROOT/design/dec/dec_ib_ctl.sv $RV_ROOT/design/dec/dec_tlu_ctl.sv -$RV_ROOT/design/dec/dec_trigger.sv -$RV_ROOT/design/dec/dec.sv -$RV_ROOT/design/exu/exu_alu_ctl.sv -$RV_ROOT/design/exu/exu_mul_ctl.sv -$RV_ROOT/design/exu/exu_div_ctl.sv -$RV_ROOT/design/exu/exu.sv -$RV_ROOT/design/lsu/lsu.sv -$RV_ROOT/design/lsu/lsu_clkdomain.sv -$RV_ROOT/design/lsu/lsu_addrcheck.sv -$RV_ROOT/design/lsu/lsu_lsc_ctl.sv +$RV_ROOT/design/dec/dec_trigger.sv +$RV_ROOT/design/dec/dec.sv +$RV_ROOT/design/exu/exu_alu_ctl.sv +$RV_ROOT/design/exu/exu_mul_ctl.sv +$RV_ROOT/design/exu/exu_div_ctl.sv +$RV_ROOT/design/exu/exu.sv +$RV_ROOT/design/lsu/lsu.sv +$RV_ROOT/design/lsu/lsu_clkdomain.sv +$RV_ROOT/design/lsu/lsu_addrcheck.sv +$RV_ROOT/design/lsu/lsu_lsc_ctl.sv $RV_ROOT/design/lsu/lsu_stbuf.sv $RV_ROOT/design/lsu/lsu_bus_read_buffer.sv $RV_ROOT/design/lsu/lsu_bus_write_buffer.sv $RV_ROOT/design/lsu/lsu_bus_intf.sv $RV_ROOT/design/lsu/lsu_ecc.sv $RV_ROOT/design/lsu/lsu_dccm_mem.sv -$RV_ROOT/design/lsu/lsu_dccm_ctl.sv -$RV_ROOT/design/lsu/lsu_trigger.sv -$RV_ROOT/design/dbg/dbg.sv -$RV_ROOT/design/dmi/dmi_wrapper.v +$RV_ROOT/design/lsu/lsu_dccm_ctl.sv +$RV_ROOT/design/lsu/lsu_trigger.sv +$RV_ROOT/design/dbg/dbg.sv +$RV_ROOT/design/dmi/dmi_wrapper.v $RV_ROOT/design/dmi/dmi_jtag_to_core_sync.v $RV_ROOT/design/dmi/rvjtag_tap.sv $RV_ROOT/design/dmi/double_flop_sync.v $RV_ROOT/design/dmi/toggle_sync.v -$RV_ROOT/design/lib/beh_lib.sv -$RV_ROOT/design/lib/mem_lib.sv -$RV_ROOT/design/lib/ahb_to_axi4.sv -$RV_ROOT/design/lib/axi4_to_ahb.sv +$RV_ROOT/design/lib/beh_lib.sv +$RV_ROOT/design/lib/mem_lib.sv +$RV_ROOT/design/lib/ahb_to_axi4.sv +$RV_ROOT/design/lib/axi4_to_ahb.sv diff --git a/design/ifu/ifu.sv b/design/ifu/ifu.sv index 65d4265..acdd803 100644 --- a/design/ifu/ifu.sv +++ b/design/ifu/ifu.sv @@ -30,9 +30,9 @@ module ifu input logic dec_ib3_valid_d, dec_ib2_valid_d, // mass balance for decode buffer - input logic dec_ib0_valid_eff_d, // effective valid taking decode into account - input logic dec_ib1_valid_eff_d, // effective valid taking decode into account - + input logic dec_ib0_valid_eff_d, // effective valid taking decode into account + input logic dec_ib1_valid_eff_d, // effective valid taking decode into account + input logic exu_i0_br_ret_e4, // i0 branch commit is a ret input logic exu_i1_br_ret_e4, // i1 branch commit is a ret input logic exu_i0_br_call_e4, // i0 branch commit is a call @@ -49,8 +49,8 @@ module ifu input logic [31:0] dec_tlu_mrac_ff ,// Side_effect , cacheable for each region input logic dec_tlu_fence_i_wb, // fence.i, invalidate icache, validated with exu_flush_final input logic dec_tlu_flush_leak_one_wb, // ignore bp for leak one fetches - - input logic dec_tlu_bpred_disable, // disable all branch prediction + + input logic dec_tlu_bpred_disable, // disable all branch prediction input logic dec_tlu_core_ecc_disable, // disable ecc checking and flagging // AXI Write Channels - IFU never writes. So, 0 out mostly @@ -66,19 +66,19 @@ module ifu output logic [3:0] ifu_axi_awcache, output logic [2:0] ifu_axi_awprot, output logic [3:0] ifu_axi_awqos, - - output logic ifu_axi_wvalid, + + output logic ifu_axi_wvalid, input logic ifu_axi_wready, output logic [63:0] ifu_axi_wdata, output logic [7:0] ifu_axi_wstrb, output logic ifu_axi_wlast, - + input logic ifu_axi_bvalid, output logic ifu_axi_bready, input logic [1:0] ifu_axi_bresp, input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic ifu_axi_arvalid, input logic ifu_axi_arready, output logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_arid, @@ -91,7 +91,7 @@ module ifu output logic [3:0] ifu_axi_arcache, output logic [2:0] ifu_axi_arprot, output logic [3:0] ifu_axi_arqos, - + input logic ifu_axi_rvalid, output logic ifu_axi_rready, input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid, @@ -100,101 +100,101 @@ module ifu input logic ifu_axi_rlast, //// AHB LITE BUS - //`ifdef RV_BUILD_AHB_LITE + //`ifdef RV_BUILD_AHB_LITE input logic ifu_bus_clk_en, - input logic dma_iccm_req, - input logic dma_iccm_stall_any, + input logic dma_iccm_req, + input logic dma_iccm_stall_any, input logic [31:0] dma_mem_addr, input logic [2:0] dma_mem_sz, input logic dma_mem_write, input logic [63:0] dma_mem_wdata, - - output logic iccm_dma_ecc_error, - output logic iccm_dma_rvalid, + + output logic iccm_dma_ecc_error, + output logic iccm_dma_rvalid, output logic [63:0] iccm_dma_rdata, output logic iccm_ready, - //`endif + //`endif output logic [1:0] ifu_pmu_instr_aligned, output logic ifu_pmu_align_stall, output logic ifu_pmu_fetch_stall, - - // I$ & ITAG Ports - output logic [31:4] ic_rw_addr, // Read/Write addresss to the Icache. + + // I$ & ITAG Ports + output logic [31:4] ic_rw_addr, // Read/Write addresss to the Icache. output logic [3:0] ic_wr_en, // Icache write enable, when filling the Icache. output logic ic_rd_en, // Icache read enable. `ifdef RV_ICACHE_ECC output logic [167:0] ic_wr_data, // Data to fill to the Icache. With ECC input logic [167:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC - input logic [24:0] ictag_debug_rd_data,// Debug icache tag. - output logic [41:0] ic_debug_wr_data, // Debug wr cache. + input logic [24:0] ictag_debug_rd_data,// Debug icache tag. + output logic [41:0] ic_debug_wr_data, // Debug wr cache. output logic [41:0] ifu_ic_debug_rd_data, -`else +`else output logic [135:0] ic_wr_data, // Data to fill to the Icache. With Parity input logic [135:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With Parity - input logic [20:0] ictag_debug_rd_data,// Debug icache tag. - output logic [33:0] ic_debug_wr_data, // Debug wr cache. + input logic [20:0] ictag_debug_rd_data,// Debug icache tag. + output logic [33:0] ic_debug_wr_data, // Debug wr cache. output logic [33:0] ifu_ic_debug_rd_data, `endif - output logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache. + output logic [127:0] ic_premux_data, // Premux data to be muxed with each way of the Icache. output logic ic_sel_premux_data, // Select the premux data. - output logic [15:2] ic_debug_addr, // Read/Write addresss to the Icache. + output logic [15:2] ic_debug_addr, // Read/Write addresss to the Icache. output logic ic_debug_rd_en, // Icache debug rd output logic ic_debug_wr_en, // Icache debug wr output logic ic_debug_tag_array, // Debug tag array output logic [3:0] ic_debug_way, // Debug way. Rd or Wr. - output logic [3:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage - - input logic [3:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage + output logic [3:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage + + input logic [3:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage input logic ic_tag_perr, // Icache Tag parity error `ifdef RV_ICCM_ENABLE - // ICCM ports + // ICCM ports output logic [`RV_ICCM_BITS-1:2] iccm_rw_addr, // ICCM read/write address. output logic iccm_wren, // ICCM write enable (through the DMA) output logic iccm_rden, // ICCM read enable. output logic [77:0] iccm_wr_data, // ICCM write data. - output logic [2:0] iccm_wr_size, // ICCM write location within DW. - + output logic [2:0] iccm_wr_size, // ICCM write location within DW. + input logic [155:0] iccm_rd_data, // Data read from ICCM. `endif // Perf counter sigs output logic ifu_pmu_ic_miss, // ic miss - output logic ifu_pmu_ic_hit, // ic hit + output logic ifu_pmu_ic_hit, // ic hit output logic ifu_pmu_bus_error, // iside bus error output logic ifu_pmu_bus_busy, // iside bus busy output logic ifu_pmu_bus_trxn, // iside bus transactions - output logic ifu_i0_valid, // Instructio 0 valid. From Aligner to Decode - output logic ifu_i1_valid, // Instructio 1 valid. From Aligner to Decode + output logic ifu_i0_valid, // Instructio 0 valid. From Aligner to Decode + output logic ifu_i1_valid, // Instructio 1 valid. From Aligner to Decode output logic ifu_i0_icaf, // Instructio 0 access fault. From Aligner to Decode - output logic ifu_i1_icaf, // Instructio 1 access fault. From Aligner to Decode + output logic ifu_i1_icaf, // Instructio 1 access fault. From Aligner to Decode output logic ifu_i0_icaf_f1, // Instruction 0 has access fault on second fetch group output logic ifu_i1_icaf_f1, // Instruction 1 has access fault on second fetch group output logic ifu_i0_perr, // Instructio 0 parity error. From Aligner to Decode - output logic ifu_i1_perr, // Instructio 1 parity error. From Aligner to Decode + output logic ifu_i1_perr, // Instructio 1 parity error. From Aligner to Decode output logic ifu_i0_sbecc, // Instruction 0 has single bit ecc error output logic ifu_i1_sbecc, // Instruction 1 has single bit ecc error output logic ifu_i0_dbecc, // Instruction 0 has double bit ecc error output logic ifu_i1_dbecc, // Instruction 1 has double bit ecc error output logic iccm_dma_sb_error, // Single Bit ECC error from a DMA access output logic[31:0] ifu_i0_instr, // Instructio 0 . From Aligner to Decode - output logic[31:0] ifu_i1_instr, // Instructio 1 . From Aligner to Decode - output logic[31:1] ifu_i0_pc, // Instructio 0 pc. From Aligner to Decode + output logic[31:0] ifu_i1_instr, // Instructio 1 . From Aligner to Decode + output logic[31:1] ifu_i0_pc, // Instructio 0 pc. From Aligner to Decode output logic[31:1] ifu_i1_pc, // Instructio 1 pc. From Aligner to Decode output logic ifu_i0_pc4, // Instructio 0 is 4 byte. From Aligner to Decode - output logic ifu_i1_pc4, // Instructio 1 is 4 byte. From Aligner to Decode + output logic ifu_i1_pc4, // Instructio 1 is 4 byte. From Aligner to Decode output logic [15:0] ifu_illegal_inst, // Illegal instruction. output logic ifu_miss_state_idle, // There is no outstanding miss. Cache miss state is idle. @@ -209,7 +209,7 @@ module ifu input br_tlu_pkt_t dec_tlu_br0_wb_pkt, // slot0 update/error pkt input br_tlu_pkt_t dec_tlu_br1_wb_pkt, // slot1 update/error pkt input dec_tlu_flush_lower_wb, - + input rets_pkt_t exu_rets_e1_pkt, // E1 return stack packet input rets_pkt_t exu_rets_e4_pkt, // E4 return stack packet @@ -225,13 +225,13 @@ module ifu output logic [15:0] ifu_i1_cinst, - /// Icache debug + /// Icache debug input cache_debug_pkt_t dec_tlu_ic_diag_pkt , output logic ifu_ic_debug_rd_data_valid, - - input logic scan_mode + + input logic scan_mode ); localparam TAGWIDTH = 2 ; @@ -245,7 +245,7 @@ module ifu logic [31:1] ifu_fetch_pc; // starting pc of fetch logic [31:1] ifc_fetch_addr_f1; - + logic ic_crit_wd_rdy; logic ic_write_stall; logic ic_dma_active; @@ -255,9 +255,9 @@ module ifu logic ic_access_fault_f2; logic ifu_ic_mb_empty; - + logic ic_hit_f2; - + // fetch control ifu_ifc_ctl ifc (.* ); @@ -278,42 +278,42 @@ module ifu logic [7:0] ifu_bp_pc4_f2; // pc4 indication; right justified logic [7:0] ifu_bp_valid_f2; // branch valid, right justified logic [`RV_BHT_GHR_RANGE] ifu_bp_fghr_f2; - + // branch predictor ifu_bp_ctl bp (.*); - + logic [7:0] ic_fetch_val_f2; logic [127:0] ic_data_f2; logic [127:0] ifu_fetch_data; logic ifc_fetch_req_f1_raw, ifc_fetch_req_f1, ifc_fetch_req_f2; - logic ic_rd_parity_final_err; // This fetch has a data_cache or tag parity error. - logic iccm_rd_ecc_single_err; // This fetch has an iccm single error. + logic ic_rd_parity_final_err; // This fetch has a data_cache or tag parity error. + logic iccm_rd_ecc_single_err; // This fetch has an iccm single error. logic iccm_rd_ecc_double_err; // This fetch has an iccm double error. icache_err_pkt_t ic_error_f2; - + logic ifu_icache_fetch_f2 ; logic [16:2] ifu_icache_error_index; // Index with parity error - logic ifu_icache_error_val; // Parity error + logic ifu_icache_error_val; // Parity error logic ifu_icache_sb_error_val; assign ifu_fetch_data[127:0] = ic_data_f2[127:0]; assign ifu_fetch_val[7:0] = ic_fetch_val_f2[7:0]; assign ifu_fetch_pc[31:1] = ifc_fetch_addr_f2[31:1]; - + // aligner ifu_aln_ctl aln (.*); // icache - ifu_mem_ctl mem_ctl + ifu_mem_ctl mem_ctl (.*, .fetch_addr_f1(ifc_fetch_addr_f1), - .ifu_icache_error_index(ifu_icache_error_index[16:6]), + .ifu_icache_error_index(ifu_icache_error_index[16:6]), .ic_hit_f2(ic_hit_f2), .ic_data_f2(ic_data_f2[127:0]) ); - + // Performance debug info @@ -371,26 +371,26 @@ module ifu `endif $display("RS_CONFIG: %d", `RV_RET_STACK_SIZE); end - if(exu_flush_final & ~(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_pkt.br_start_error | dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_pkt.br_start_error) & (exu_mp_pkt.misp | exu_mp_pkt.ataken)) + if(exu_flush_final & ~(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_pkt.br_start_error | dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_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[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO], exu_mp_bank[1:0], exu_mp_call, exu_mp_ret, exu_mp_ataken, exu_mp_hist[1:0], exu_mp_valid, exu_mp_pkt.btag[`RV_BTB_BTAG_SIZE-1:0], {exu_flush_path_final[31:1], 1'b0}, exu_mp_eghr[`RV_BHT_GHR_RANGE], exu_mp_valid, bp.bht_wr_addr0, mppc[31:0], exu_mp_pkt.way); for(int i = 0; i < 8; i++) begin - if(ifu_bp_valid_f2[i] & ifc_fetch_req_f2) + if(ifu_bp_valid_f2[i] & ifc_fetch_req_f2) $display("%7d BTB_HIT : index: %0h bank: %0h call: %b ret: %b taken: %b strength: %b tag: %h targ: %h ghr: %4b ghr_index: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,btb_rd_addr_f2[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],encode8_3(bp.btb_sel_f2[7:0]), bp.btb_rd_call_f2, bp.btb_rd_ret_f2, ifu_bp_hist1_f2[tmp_bnk], ifu_bp_hist0_f2[tmp_bnk], bp.fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0], {ifu_bp_btb_target_f2[31:1], 1'b0}, bp.fghr[`RV_BHT_GHR_RANGE], bp.bht_rd_addr_f1, ifu_bp_way_f2[tmp_bnk]); end `ifdef RV_BTB_48 for(int y = 0; y < 4; y++) begin for(int z = 0; z < 4; z++) begin if(bp.lru_bank_sel[y][z]) - $display("%7d BTB_LRU: index: %0h bank: %0h newlru %h", `DEC.tlu.mcyclel[31:0]+32'ha, z,y,bp.lru_bank_wr_data[y][z]); + $display("%7d BTB_LRU: index: %0h bank: %0h newlru %h", `DEC.tlu.mcyclel[31:0]+32'ha, z,y,bp.lru_bank_wr_data[y][z]); end end - `endif + `endif if(dec_tlu_br0_wb_pkt.valid & ~(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_pkt.br_start_error)) - $display("%7d BTB_UPD0: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br0_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br0_wb_pkt.bank[1:0],dec_tlu_br0_wb_pkt.middle}, dec_tlu_br0_wb_pkt.hist, dec_tlu_br0_wb_pkt.way); + $display("%7d BTB_UPD0: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br0_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br0_wb_pkt.bank[1:0],dec_tlu_br0_wb_pkt.middle}, dec_tlu_br0_wb_pkt.hist, dec_tlu_br0_wb_pkt.way); if(dec_tlu_br1_wb_pkt.valid & ~(dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_pkt.br_start_error)) - $display("%7d BTB_UPD1: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br1_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br1_wb_pkt.bank[1:0],dec_tlu_br1_wb_pkt.middle}, dec_tlu_br1_wb_pkt.hist, dec_tlu_br1_wb_pkt.way); + $display("%7d BTB_UPD1: ghr_index: %0h bank: %0h hist: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,bp.br1_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO],{dec_tlu_br1_wb_pkt.bank[1:0],dec_tlu_br1_wb_pkt.middle}, dec_tlu_br1_wb_pkt.hist, dec_tlu_br1_wb_pkt.way); if(dec_tlu_br0_wb_pkt.br_error | dec_tlu_br0_wb_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,dec_tlu_br0_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],dec_tlu_br0_wb_pkt.bank[1:0], dec_tlu_br0_wb_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br0_wb_pkt.way); + $display("%7d BTB_ERR0: index: %0h bank: %0h start: %b rfpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,dec_tlu_br0_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],dec_tlu_br0_wb_pkt.bank[1:0], dec_tlu_br0_wb_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br0_wb_pkt.way); if(dec_tlu_br1_wb_pkt.br_error | dec_tlu_br1_wb_pkt.br_start_error) $display("%7d BTB_ERR1: index: %0h bank: %0h start: %b rfpc: %h way: %h", `DEC.tlu.mcyclel[31:0]+32'ha,dec_tlu_br1_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO],dec_tlu_br1_wb_pkt.bank[1:0], dec_tlu_br1_wb_pkt.br_start_error, {exu_flush_path_final[31:1], 1'b0}, dec_tlu_br1_wb_pkt.way); end // always @ (negedge clk) @@ -401,6 +401,6 @@ module ifu encode8_3[1] = in[7] | in[6] | in[3] | in[2]; encode8_3[0] = in[7] | in[5] | in[3] | in[1]; - endfunction + endfunction `endif endmodule // ifu diff --git a/design/ifu/ifu_aln_ctl.sv b/design/ifu/ifu_aln_ctl.sv index 4e211a9..a604d78 100644 --- a/design/ifu/ifu_aln_ctl.sv +++ b/design/ifu/ifu_aln_ctl.sv @@ -23,8 +23,8 @@ module ifu_aln_ctl ( input logic active_clk, - - input logic iccm_rd_ecc_single_err, // This fetch has a single ICCM ecc error. + + input logic iccm_rd_ecc_single_err, // This fetch has a single ICCM ecc error. input logic iccm_rd_ecc_double_err, // This fetch has a double ICCM ecc error. input logic ic_rd_parity_final_err, // for tag parity errors @@ -35,7 +35,7 @@ module ifu_aln_ctl input logic [31:1] ifu_bp_btb_target_f2, // predicted RET target input logic [11:0] ifu_bp_poffset_f2, // predicted target offset - input logic [7:0] ifu_bp_hist0_f2, // history counters for all 4 potential branches, bit 1, right justified + input logic [7:0] ifu_bp_hist0_f2, // history counters for all 4 potential branches, bit 1, right justified input logic [7:0] ifu_bp_hist1_f2, // history counters for all 4 potential branches, bit 1, right justified input logic [7:0] ifu_bp_pc4_f2, // pc4 indication, right justified `ifdef RV_BTB_48 @@ -47,30 +47,30 @@ module ifu_aln_ctl input logic [7:0] ifu_bp_ret_f2, // predicted ret indication, right justified input logic exu_flush_final, // Flush from the pipeline. - + input logic dec_ib3_valid_d, // valids for top 2 instruction buffers at decode input logic dec_ib2_valid_d, - input logic dec_ib0_valid_eff_d, // effective valid taking decode into account + input logic dec_ib0_valid_eff_d, // effective valid taking decode into account input logic dec_ib1_valid_eff_d, - - + + input logic [127:0] ifu_fetch_data, // fetch data in memory format - not right justified input icache_err_pkt_t ic_error_f2, // based on configuration: either parity or ecc - + input logic [7:0] ifu_fetch_val, // valids on a 2B boundary, right justified input logic [31:1] ifu_fetch_pc, // starting pc of fetch - + input logic rst_l, input logic clk, input logic dec_tlu_core_ecc_disable, // disable ecc checking and flagging - output logic ifu_i0_valid, // Instruction 0 is valid + output logic ifu_i0_valid, // Instruction 0 is valid output logic ifu_i1_valid, // Instruction 1 is valid - output logic ifu_i0_icaf, // Instruction 0 has access fault + output logic ifu_i0_icaf, // Instruction 0 has access fault output logic ifu_i1_icaf, // Instruction 1 has access fault output logic ifu_i0_icaf_f1, // Instruction 0 has access fault on second fetch group output logic ifu_i1_icaf_f1, // Instruction 1 has access fault on second fetch group @@ -80,14 +80,14 @@ module ifu_aln_ctl output logic ifu_i1_sbecc, // Instruction 1 has single bit ecc error output logic ifu_i0_dbecc, // Instruction 0 has double bit ecc error output logic ifu_i1_dbecc, // Instruction 1 has double bit ecc error - output logic [31:0] ifu_i0_instr, // Instruction 0 + output logic [31:0] ifu_i0_instr, // Instruction 0 output logic [31:0] ifu_i1_instr, // Instruction 1 - output logic [31:1] ifu_i0_pc, // Instruction 0 PC - output logic [31:1] ifu_i1_pc, // Instruction 1 PC + output logic [31:1] ifu_i0_pc, // Instruction 0 PC + output logic [31:1] ifu_i1_pc, // Instruction 1 PC output logic ifu_i0_pc4, - output logic ifu_i1_pc4, - - output logic ifu_fb_consume1, // Consumed one buffer. To fetch control fetch for buffer mass balance + output logic ifu_i1_pc4, + + output logic ifu_fb_consume1, // Consumed one buffer. To fetch control fetch for buffer mass balance output logic ifu_fb_consume2, // Consumed two buffers.To fetch control fetch for buffer mass balance output logic [15:0] ifu_illegal_inst, // Illegal Instruction. @@ -97,35 +97,35 @@ module ifu_aln_ctl output logic [1:0] ifu_pmu_instr_aligned, // number of inst aligned this cycle output logic ifu_pmu_align_stall, // aligner stalled this cycle - output logic [16:2] ifu_icache_error_index, // Icache Error address index + output logic [16:2] ifu_icache_error_index, // Icache Error address index output logic ifu_icache_error_val, // Icache error valid - output logic ifu_icache_sb_error_val, + output logic ifu_icache_sb_error_val, output logic [15:0] ifu_i0_cinst, // 16b compress inst for i0 output logic [15:0] ifu_i1_cinst, // 16b compress inst for i1 input logic scan_mode - - + + ); `include "global.h" - + logic ifvalid; logic shift_f1_f0, shift_f2_f0, shift_f2_f1; logic fetch_to_f0, fetch_to_f1, fetch_to_f2; logic [7:0] f2val_in, f2val; logic [7:0] f1val_in, f1val; - logic [7:0] f0val_in, f0val; - + logic [7:0] f0val_in, f0val; + logic [7:0] sf1val, sf0val; logic [31:1] f2pc_in, f2pc; logic [31:1] f1pc_in, f1pc; - logic [31:1] f0pc_in, f0pc; + logic [31:1] f0pc_in, f0pc; logic [31:1] sf1pc, sf0pc; - + logic [63:0] aligndata; logic first4B, first2B; logic second4B, second2B; @@ -138,45 +138,45 @@ module ifu_aln_ctl logic shift_2B, shift_4B, shift_6B, shift_8B; logic f1_shift_2B, f1_shift_4B, f1_shift_6B; logic f2_valid, sf1_valid, sf0_valid; - + logic [31:0] ifirst, isecond, ithird; logic [31:1] f0pc_plus1, f0pc_plus2, f0pc_plus3, f0pc_plus4; - logic [31:1] f1pc_plus1, f1pc_plus2, f1pc_plus3; + logic [31:1] f1pc_plus1, f1pc_plus2, f1pc_plus3; logic [3:0] alignval; logic [31:1] firstpc, secondpc, thirdpc, fourthpc; - + logic [11:0] f1poffset; - logic [11:0] f0poffset; + logic [11:0] f0poffset; logic [`RV_BHT_GHR_RANGE] f1fghr; - logic [`RV_BHT_GHR_RANGE] f0fghr; + logic [`RV_BHT_GHR_RANGE] f0fghr; logic [7:0] f1hist1; - logic [7:0] f0hist1; + logic [7:0] f0hist1; logic [7:0] f1hist0; - logic [7:0] f0hist0; + logic [7:0] f0hist0; logic [7:0] f1pc4; - logic [7:0] f0pc4; + logic [7:0] f0pc4; logic [7:0] f1ret; - logic [7:0] f0ret; + logic [7:0] f0ret; `ifdef RV_BTB_48 logic [7:0][1:0] f1way; - logic [7:0][1:0] f0way; + logic [7:0][1:0] f0way; `else logic [7:0] f1way; - logic [7:0] f0way; + logic [7:0] f0way; `endif - + logic [7:0] f1brend; - logic [7:0] f0brend; + logic [7:0] f0brend; logic [3:0] alignbrend; logic [3:0] alignpc4; `ifdef RV_ICACHE_ECC - logic [19:0] alignecc; -`else + logic [19:0] alignecc; +`else logic [3:0] alignparity; `endif - logic [3:0] alignret; + logic [3:0] alignret; logic [3:0] alignway; logic [3:0] alignhist1; @@ -197,13 +197,13 @@ module ifu_aln_ctl logic f0icfetch; logic f1icaf; logic f0icaf; - + logic [3:0] alignicfetch; - logic [3:0] aligntagperr; - logic [3:0] aligndataperr; + logic [3:0] aligntagperr; + logic [3:0] aligndataperr; logic [3:0] alignsbecc; logic [3:0] aligndbecc; - logic [3:0] alignicaf; + logic [3:0] alignicaf; logic i0_brp_pc4, i1_brp_pc4; logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] firstpc_hash, secondpc_hash, thirdpc_hash, fourthpc_hash; @@ -216,34 +216,34 @@ module ifu_aln_ctl logic illegal_lockout_in, illegal_lockout; logic [3:0] alignfinalperr; - + logic f2_wr_en; assign f2_wr_en = fetch_to_f2; - + logic f0_shift_wr_en; assign f0_shift_wr_en = (fetch_to_f0 | shift_f2_f0 | shift_f1_f0 | shift_2B | shift_4B | shift_6B | shift_8B); - + logic f1_shift_wr_en; assign f1_shift_wr_en = (fetch_to_f1 | shift_f2_f1 | f1_shift_2B | f1_shift_4B | f1_shift_6B); logic [1:0] wrptr, wrptr_in; - logic [1:0] rdptr, rdptr_in; + logic [1:0] rdptr, rdptr_in; logic [2:0] qwen; logic [127:0] q2,q1,q0; logic [2:0] first_offset, second_offset; logic [2:0] q2off_eff, q2off_in, q2off; logic [2:0] q1off_eff, q1off_in, q1off; - logic [2:0] q0off_eff, q0off_in, q0off; + logic [2:0] q0off_eff, q0off_in, q0off; logic f0_shift_2B, f0_shift_4B, f0_shift_6B, f0_shift_8B; logic [127:0] q0eff; logic [127:0] q0final; logic [2:0] q0ptr; logic [7:0] q0sel; - + logic [127:0] q1eff; logic [127:0] q1final; logic [2:0] q1ptr; @@ -253,24 +253,24 @@ module ifu_aln_ctl logic consume_fb1, consume_fb0; logic [3:1] icaf_eff; - + `ifdef RV_ICACHE_ECC logic [39:0] q0ecc, q1ecc, q2ecc; - logic [39:0] q0ecceff, q1ecceff; + logic [39:0] q0ecceff, q1ecceff; logic [39:0] q0eccfinal, q1eccfinal; -`else +`else logic [7:0] q0parity, q1parity, q2parity; - logic [7:0] q0parityeff, q1parityeff; + logic [7:0] q0parityeff, q1parityeff; logic [7:0] q0parityfinal, q1parityfinal; `endif // new queue control logic - + assign wrptr_in[1:0] = (({2{wrptr[1:0]==2'b00 & ifvalid}} & 2'b01) | ({2{wrptr[1:0]==2'b01 & ifvalid}} & 2'b10) | ({2{wrptr[1:0]==2'b10 & ifvalid}} & 2'b00) | ({2{~ifvalid}} & wrptr[1:0])) & ~{2{exu_flush_final}}; - + rvdff #(2) wrpff (.*, .clk(active_clk), .din(wrptr_in[1:0]), .dout(wrptr[1:0])); assign rdptr_in[1:0] = (({2{rdptr[1:0]==2'b00 & ifu_fb_consume1}} & 2'b01) | @@ -280,29 +280,29 @@ module ifu_aln_ctl ({2{rdptr[1:0]==2'b01 & ifu_fb_consume2}} & 2'b00) | ({2{rdptr[1:0]==2'b10 & ifu_fb_consume2}} & 2'b01) | ({2{~ifu_fb_consume1&~ifu_fb_consume2}} & rdptr[1:0])) & ~{2{exu_flush_final}}; - + rvdff #(2) rdpff (.*, .clk(active_clk), .din(rdptr_in[1:0]), .dout(rdptr[1:0])); - + assign qren[2:0] = { rdptr[1:0]==2'b10, rdptr[1:0]==2'b01, - rdptr[1:0]==2'b00 + rdptr[1:0]==2'b00 }; 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 first_offset[2:0] = {f0_shift_8B, f0_shift_6B|f0_shift_4B, f0_shift_6B|f0_shift_2B }; - + assign second_offset[2:0] = {1'b0, f1_shift_6B|f1_shift_4B, f1_shift_6B|f1_shift_2B }; - - + + assign q2off_eff[2:0] = (rdptr[1:0]==2'd2) ? (q2off[2:0] + first_offset[2:0]) : (rdptr[1:0]==2'd1) ? (q2off[2:0] + second_offset[2:0]) : q2off[2:0]; - + assign q2off_in[2:0] = (qwen[2]) ? ifu_fetch_pc[3:1] : q2off_eff[2:0]; rvdff #(3) q2offsetff (.*, .clk(active_clk), .din(q2off_in[2:0]), .dout(q2off[2:0])); @@ -310,8 +310,8 @@ module ifu_aln_ctl assign q1off_eff[2:0] = (rdptr[1:0]==2'd1) ? (q1off[2:0] + first_offset[2:0]) : (rdptr[1:0]==2'd0) ? (q1off[2:0] + second_offset[2:0]) : q1off[2:0]; - - + + assign q1off_in[2:0] = (qwen[1]) ? ifu_fetch_pc[3:1] : q1off_eff[2:0]; rvdff #(3) q1offsetff (.*, .clk(active_clk), .din(q1off_in[2:0]), .dout(q1off[2:0])); @@ -320,17 +320,17 @@ module ifu_aln_ctl assign q0off_eff[2:0] = (rdptr[1:0]==2'd0) ? (q0off[2:0] + first_offset[2:0]) : (rdptr[1:0]==2'd2) ? (q0off[2:0] + second_offset[2:0]) : q0off[2:0]; - - + + assign q0off_in[2:0] = (qwen[0]) ? ifu_fetch_pc[3:1] : q0off_eff[2:0]; - - rvdff #(3) q0offsetff (.*, .clk(active_clk), .din(q0off_in[2:0]), .dout(q0off[2:0])); + + rvdff #(3) q0offsetff (.*, .clk(active_clk), .din(q0off_in[2:0]), .dout(q0off[2:0])); assign q0ptr[2:0] = (({3{rdptr[1:0]==2'b00}} & q0off[2:0]) | ({3{rdptr[1:0]==2'b01}} & q1off[2:0]) | ({3{rdptr[1:0]==2'b10}} & q2off[2:0])); - + assign q1ptr[2:0] = (({3{rdptr[1:0]==2'b00}} & q1off[2:0]) | ({3{rdptr[1:0]==2'b01}} & q2off[2:0]) | ({3{rdptr[1:0]==2'b10}} & q0off[2:0])); @@ -344,7 +344,7 @@ module ifu_aln_ctl q0ptr[2:0]==3'b001, q0ptr[2:0]==3'b000 }; - + assign q1sel[7:0] = { q1ptr[2:0]==3'b111, q1ptr[2:0]==3'b110, q1ptr[2:0]==3'b101, @@ -354,18 +354,18 @@ module ifu_aln_ctl q1ptr[2:0]==3'b001, q1ptr[2:0]==3'b000 }; - + // end new queue control logic - + // misc data that is associated with each fetch buffer localparam MHI = 47+`RV_BHT_GHR_SIZE; localparam MSIZE = 48+`RV_BHT_GHR_SIZE; - + logic [MHI:0] misc_data_in, misc2, misc1, misc0; logic [MHI:0] misc1eff, misc0eff; - + assign misc_data_in[MHI:0] = { iccm_rd_ecc_double_err, iccm_rd_ecc_single_err, ifu_icache_fetch_f2, @@ -378,7 +378,7 @@ module ifu_aln_ctl rvdffe #(MSIZE) misc2ff (.*, .en(qwen[2]), .din(misc_data_in[MHI:0]), .dout(misc2[MHI:0])); rvdffe #(MSIZE) misc1ff (.*, .en(qwen[1]), .din(misc_data_in[MHI:0]), .dout(misc1[MHI:0])); - rvdffe #(MSIZE) misc0ff (.*, .en(qwen[0]), .din(misc_data_in[MHI:0]), .dout(misc0[MHI:0])); + rvdffe #(MSIZE) misc0ff (.*, .en(qwen[0]), .din(misc_data_in[MHI:0]), .dout(misc0[MHI:0])); assign {misc1eff[MHI:0],misc0eff[MHI:0]} = (({MSIZE*2{qren[0]}} & {misc1[MHI:0],misc0[MHI:0]}) | @@ -391,9 +391,9 @@ module ifu_aln_ctl f1icaf, f1prett[31:1], f1poffset[11:0], - f1fghr[`RV_BHT_GHR_RANGE] + f1fghr[`RV_BHT_GHR_RANGE] } = misc1eff[MHI:0]; - + assign { f0dbecc, f0sbecc, f0icfetch, @@ -403,7 +403,7 @@ module ifu_aln_ctl f0poffset[11:0], f0fghr[`RV_BHT_GHR_RANGE] } = misc0eff[MHI:0]; - + `ifdef RV_BTB_48 localparam BRDATA_SIZE=56; @@ -414,8 +414,8 @@ module ifu_aln_ctl `endif logic [BRDATA_SIZE-1:0] brdata_in, brdata2, brdata1, brdata0; logic [BRDATA_SIZE-1:0] brdata1eff, brdata0eff; - logic [BRDATA_SIZE-1:0] brdata1final, brdata0final; - assign brdata_in[BRDATA_SIZE-1:0] = { + logic [BRDATA_SIZE-1:0] brdata1final, brdata0final; + assign brdata_in[BRDATA_SIZE-1:0] = { ifu_bp_hist1_f2[7],ifu_bp_hist0_f2[7],ifu_bp_pc4_f2[7],ifu_bp_way_f2[7],ifu_bp_valid_f2[7],ifu_bp_ret_f2[7], ifu_bp_hist1_f2[6],ifu_bp_hist0_f2[6],ifu_bp_pc4_f2[6],ifu_bp_way_f2[6],ifu_bp_valid_f2[6],ifu_bp_ret_f2[6], ifu_bp_hist1_f2[5],ifu_bp_hist0_f2[5],ifu_bp_pc4_f2[5],ifu_bp_way_f2[5],ifu_bp_valid_f2[5],ifu_bp_ret_f2[5], @@ -425,35 +425,35 @@ module ifu_aln_ctl ifu_bp_hist1_f2[1],ifu_bp_hist0_f2[1],ifu_bp_pc4_f2[1],ifu_bp_way_f2[1],ifu_bp_valid_f2[1],ifu_bp_ret_f2[1], ifu_bp_hist1_f2[0],ifu_bp_hist0_f2[0],ifu_bp_pc4_f2[0],ifu_bp_way_f2[0],ifu_bp_valid_f2[0],ifu_bp_ret_f2[0] }; - // + // rvdffe #(BRDATA_SIZE) brdata2ff (.*, .en(qwen[2]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata2[BRDATA_SIZE-1:0])); rvdffe #(BRDATA_SIZE) brdata1ff (.*, .en(qwen[1]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata1[BRDATA_SIZE-1:0])); - rvdffe #(BRDATA_SIZE) brdata0ff (.*, .en(qwen[0]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata0[BRDATA_SIZE-1:0])); + rvdffe #(BRDATA_SIZE) brdata0ff (.*, .en(qwen[0]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata0[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]}) | ({BRDATA_SIZE*2{qren[2]}} & {brdata0[BRDATA_SIZE-1:0],brdata2[BRDATA_SIZE-1:0]})); - + assign brdata0final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q0sel[0]}} & { brdata0eff[8*6-1:0*6]}) | - ({BRDATA_SIZE{q0sel[1]}} & {{1*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:1*BRDATA_WIDTH]}) | + ({BRDATA_SIZE{q0sel[1]}} & {{1*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:1*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q0sel[2]}} & {{2*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:2*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q0sel[3]}} & {{3*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:3*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q0sel[4]}} & {{4*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:4*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q0sel[5]}} & {{5*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:5*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q0sel[6]}} & {{6*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:6*BRDATA_WIDTH]}) | - ({BRDATA_SIZE{q0sel[7]}} & {{7*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:7*BRDATA_WIDTH]})); - + ({BRDATA_SIZE{q0sel[7]}} & {{7*BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:7*BRDATA_WIDTH]})); + assign brdata1final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q1sel[0]}} & { brdata1eff[8*6-1:0*6]}) | - ({BRDATA_SIZE{q1sel[1]}} & {{1*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:1*BRDATA_WIDTH]}) | + ({BRDATA_SIZE{q1sel[1]}} & {{1*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:1*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q1sel[2]}} & {{2*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:2*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q1sel[3]}} & {{3*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:3*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q1sel[4]}} & {{4*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:4*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q1sel[5]}} & {{5*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:5*BRDATA_WIDTH]}) | ({BRDATA_SIZE{q1sel[6]}} & {{6*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:6*BRDATA_WIDTH]}) | - ({BRDATA_SIZE{q1sel[7]}} & {{7*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:7*BRDATA_WIDTH]})); + ({BRDATA_SIZE{q1sel[7]}} & {{7*BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:7*BRDATA_WIDTH]})); - assign { + assign { f0hist1[7],f0hist0[7],f0pc4[7],f0way[7],f0brend[7],f0ret[7], f0hist1[6],f0hist0[6],f0pc4[6],f0way[6],f0brend[6],f0ret[6], f0hist1[5],f0hist0[5],f0pc4[5],f0way[5],f0brend[5],f0ret[5], @@ -463,8 +463,8 @@ module ifu_aln_ctl f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1], f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0] } = brdata0final[BRDATA_SIZE-1:0]; - - assign { + + assign { f1hist1[7],f1hist0[7],f1pc4[7],f1way[7],f1brend[7],f1ret[7], f1hist1[6],f1hist0[6],f1pc4[6],f1way[6],f1brend[6],f1ret[6], f1hist1[5],f1hist0[5],f1pc4[5],f1way[5],f1brend[5],f1ret[5], @@ -474,29 +474,29 @@ module ifu_aln_ctl f1hist1[1],f1hist0[1],f1pc4[1],f1way[1],f1brend[1],f1ret[1], f1hist1[0],f1hist0[0],f1pc4[0],f1way[0],f1brend[0],f1ret[0] } = brdata1final[BRDATA_SIZE-1:0]; - + // possible states of { sf0_valid, sf1_valid, f2_valid } // 000 if->f0 - + // 100 if->f1 - + // 101 illegal - + // 010 f1->f0, if->f1 - + // 110 if->f2 - + // 001 if->f1, f2->f0 - + // 011 f1->f0, f2->f1, if->f2 - + // 111 !if, no shift assign f2_valid = f2val[0]; - assign sf1_valid = sf1val[0]; + assign sf1_valid = sf1val[0]; assign sf0_valid = sf0val[0]; @@ -505,13 +505,13 @@ module ifu_aln_ctl assign consume_fb0 = ~sf0val[0] & f0val[0]; assign consume_fb1 = ~sf1val[0] & f1val[0]; - + assign ifu_fb_consume1 = consume_fb0 & ~consume_fb1 & ~exu_flush_final; - assign ifu_fb_consume2 = consume_fb0 & consume_fb1 & ~exu_flush_final; - + assign ifu_fb_consume2 = consume_fb0 & consume_fb1 & ~exu_flush_final; + assign ifvalid = ifu_fetch_val[0]; - + assign shift_f1_f0 = ~sf0_valid & sf1_valid; assign shift_f2_f0 = ~sf0_valid & ~sf1_valid & f2_valid; @@ -528,9 +528,9 @@ module ifu_aln_ctl ( sf0_valid & sf1_valid & ~f2_valid & ifvalid); // f0 valid states - // + // // 11111111 - // 11111110 + // 11111110 // 11111100 // 11111000 // 11110000 @@ -538,30 +538,30 @@ module ifu_aln_ctl // 11100000 // 11000000 // 10000000 - // 00000000 + // 00000000 // make this two incrementors with some logic on the lower bits - + assign f0pc_plus1[31:1] = f0pc[31:1] + 31'd1; assign f0pc_plus2[31:1] = f0pc[31:1] + 31'd2; assign f0pc_plus3[31:1] = f0pc[31:1] + 31'd3; assign f0pc_plus4[31:1] = f0pc[31:1] + 31'd4; assign f1pc_plus1[31:1] = f1pc[31:1] + 31'd1; - assign f1pc_plus2[31:1] = f1pc[31:1] + 31'd2; - assign f1pc_plus3[31:1] = f1pc[31:1] + 31'd3; + assign f1pc_plus2[31:1] = f1pc[31:1] + 31'd2; + assign f1pc_plus3[31:1] = f1pc[31:1] + 31'd3; assign f2pc_in[31:1] = ifu_fetch_pc[31:1]; - + rvdffe #(31) f2pcff (.*, .en(f2_wr_en), .din(f2pc_in[31:1]), .dout(f2pc[31:1])); assign sf1pc[31:1] = ({31{f1_shift_2B}} & (f1pc_plus1[31:1])) | ({31{f1_shift_4B}} & (f1pc_plus2[31:1])) | ({31{f1_shift_6B}} & (f1pc_plus3[31:1])) | ({31{~f1_shift_2B&~f1_shift_4B&~f1_shift_6B}} & f1pc[31:1]); - + assign f1pc_in[31:1] = ({31{fetch_to_f1}} & ifu_fetch_pc[31:1]) | ({31{shift_f2_f1}} & f2pc[31:1]) | ({31{~fetch_to_f1&~shift_f2_f1}} & sf1pc[31:1]); @@ -572,10 +572,10 @@ module ifu_aln_ctl ({31{shift_4B}} & (f0pc_plus2[31:1])) | ({31{shift_6B}} & (f0pc_plus3[31:1])) | ({31{shift_8B}} & (f0pc_plus4[31:1])); - + assign f0pc_in[31:1] = ({31{fetch_to_f0}} & ifu_fetch_pc[31:1]) | ({31{shift_f2_f0}} & f2pc[31:1]) | - ({31{shift_f1_f0}} & sf1pc[31:1]) | + ({31{shift_f1_f0}} & sf1pc[31:1]) | ({31{~fetch_to_f0&~shift_f2_f0&~shift_f1_f0}} & sf0pc[31:1]); rvdffe #(31) f0pcff (.*, .en(f0_shift_wr_en), .din(f0pc_in[31:1]), .dout(f0pc[31:1])); @@ -593,7 +593,7 @@ module ifu_aln_ctl ({8{f1_shift_4B}} & {2'b0,f1val[7:2]}) | ({8{f1_shift_6B}} & {3'b0,f1val[7:3]}) | ({8{~f1_shift_2B&~f1_shift_4B&~f1_shift_6B}} & f1val[7:0]); - + assign f1val_in[7:0] = (({8{fetch_to_f1}} & ifu_fetch_val[7:0]) | ({8{shift_f2_f1}} & f2val[7:0]) | ({8{~fetch_to_f1&~shift_f2_f1&~shift_f1_f0}} & sf1val[7:0])) & ~{8{exu_flush_final}}; @@ -606,12 +606,12 @@ module ifu_aln_ctl ({8{shift_6B}} & {3'b0,f0val[7:3]}) | ({8{shift_8B}} & {4'b0,f0val[7:4]}) | ({8{~shift_2B&~shift_4B&~shift_6B&~shift_8B}} & f0val[7:0]); - + assign f0val_in[7:0] = (({8{fetch_to_f0}} & ifu_fetch_val[7:0]) | ({8{shift_f2_f0}} & f2val[7:0]) | - ({8{shift_f1_f0}} & sf1val[7:0]) | + ({8{shift_f1_f0}} & sf1val[7:0]) | ({8{~fetch_to_f0&~shift_f2_f0&~shift_f1_f0}} & sf0val[7:0])) & ~{8{exu_flush_final}}; - + rvdff #(8) f0valff (.*, .clk(active_clk), .din(f0val_in[7:0]), .dout(f0val[7:0])); // parity @@ -619,154 +619,154 @@ module ifu_aln_ctl `ifdef RV_ICACHE_ECC rvdffe #(40) q2eccff (.*, .en(qwen[2]), .din(ic_error_f2.ecc[39:0]), .dout(q2ecc[39:0])); rvdffe #(40) q1eccff (.*, .en(qwen[1]), .din(ic_error_f2.ecc[39:0]), .dout(q1ecc[39:0])); - rvdffe #(40) q0eccff (.*, .en(qwen[0]), .din(ic_error_f2.ecc[39:0]), .dout(q0ecc[39:0])); + rvdffe #(40) q0eccff (.*, .en(qwen[0]), .din(ic_error_f2.ecc[39:0]), .dout(q0ecc[39:0])); assign {q1ecceff[39:0],q0ecceff[39:0]} = (({80{qren[0]}} & {q1ecc[39:0],q0ecc[39:0]}) | ({80{qren[1]}} & {q2ecc[39:0],q1ecc[39:0]}) | ({80{qren[2]}} & {q0ecc[39:0],q2ecc[39:0]})); - + assign q0eccfinal[39:0] = (({40{q0sel[0]}} & { q0ecceff[8*5-1:0*5]}) | - ({40{q0sel[1]}} & { 5'b0,q0ecceff[8*5-1:1*5]}) | + ({40{q0sel[1]}} & { 5'b0,q0ecceff[8*5-1:1*5]}) | ({40{q0sel[2]}} & {10'b0,q0ecceff[8*5-1:2*5]}) | ({40{q0sel[3]}} & {15'b0,q0ecceff[8*5-1:3*5]}) | ({40{q0sel[4]}} & {20'b0,q0ecceff[8*5-1:4*5]}) | ({40{q0sel[5]}} & {25'b0,q0ecceff[8*5-1:5*5]}) | ({40{q0sel[6]}} & {30'b0,q0ecceff[8*5-1:6*5]}) | - ({40{q0sel[7]}} & {35'b0,q0ecceff[8*5-1:7*5]})); + ({40{q0sel[7]}} & {35'b0,q0ecceff[8*5-1:7*5]})); assign q1eccfinal[39:0] = (({40{q1sel[0]}} & { q1ecceff[8*5-1:0*5]}) | - ({40{q1sel[1]}} & { 5'b0,q1ecceff[8*5-1:1*5]}) | + ({40{q1sel[1]}} & { 5'b0,q1ecceff[8*5-1:1*5]}) | ({40{q1sel[2]}} & {10'b0,q1ecceff[8*5-1:2*5]}) | ({40{q1sel[3]}} & {15'b0,q1ecceff[8*5-1:3*5]}) | ({40{q1sel[4]}} & {20'b0,q1ecceff[8*5-1:4*5]}) | ({40{q1sel[5]}} & {25'b0,q1ecceff[8*5-1:5*5]}) | ({40{q1sel[6]}} & {30'b0,q1ecceff[8*5-1:6*5]}) | - ({40{q1sel[7]}} & {35'b0,q1ecceff[8*5-1:7*5]})); - -`else + ({40{q1sel[7]}} & {35'b0,q1ecceff[8*5-1:7*5]})); + +`else rvdffe #(8) q2parityff (.*, .en(qwen[2]), .din(ic_error_f2.parity[7:0]), .dout(q2parity[7:0])); rvdffe #(8) q1parityff (.*, .en(qwen[1]), .din(ic_error_f2.parity[7:0]), .dout(q1parity[7:0])); - rvdffe #(8) q0parityff (.*, .en(qwen[0]), .din(ic_error_f2.parity[7:0]), .dout(q0parity[7:0])); + rvdffe #(8) q0parityff (.*, .en(qwen[0]), .din(ic_error_f2.parity[7:0]), .dout(q0parity[7:0])); assign {q1parityeff[7:0],q0parityeff[7:0]} = (({16{qren[0]}} & {q1parity[7:0],q0parity[7:0]}) | ({16{qren[1]}} & {q2parity[7:0],q1parity[7:0]}) | ({16{qren[2]}} & {q0parity[7:0],q2parity[7:0]})); - + assign q0parityfinal[7:0] = (({8{q0sel[0]}} & { q0parityeff[7:0]}) | - ({8{q0sel[1]}} & {1'b0,q0parityeff[7:1]}) | + ({8{q0sel[1]}} & {1'b0,q0parityeff[7:1]}) | ({8{q0sel[2]}} & {2'b0,q0parityeff[7:2]}) | ({8{q0sel[3]}} & {3'b0,q0parityeff[7:3]}) | ({8{q0sel[4]}} & {4'b0,q0parityeff[7:4]}) | ({8{q0sel[5]}} & {5'b0,q0parityeff[7:5]}) | ({8{q0sel[6]}} & {6'b0,q0parityeff[7:6]}) | - ({8{q0sel[7]}} & {7'b0,q0parityeff[7]})); - + ({8{q0sel[7]}} & {7'b0,q0parityeff[7]})); + assign q1parityfinal[7:0] = (({8{q1sel[0]}} & { q1parityeff[7:0]}) | - ({8{q1sel[1]}} & {1'b0,q1parityeff[7:1]}) | + ({8{q1sel[1]}} & {1'b0,q1parityeff[7:1]}) | ({8{q1sel[2]}} & {2'b0,q1parityeff[7:2]}) | ({8{q1sel[3]}} & {3'b0,q1parityeff[7:3]}) | ({8{q1sel[4]}} & {4'b0,q1parityeff[7:4]}) | ({8{q1sel[5]}} & {5'b0,q1parityeff[7:5]}) | ({8{q1sel[6]}} & {6'b0,q1parityeff[7:6]}) | - ({8{q1sel[7]}} & {7'b0,q1parityeff[7]})); + ({8{q1sel[7]}} & {7'b0,q1parityeff[7]})); `endif // !`ifdef RV_ICACHE_ECC - + rvdffe #(128) q2ff (.*, .en(qwen[2]), .din(ifu_fetch_data[127:0]), .dout(q2[127:0])); rvdffe #(128) q1ff (.*, .en(qwen[1]), .din(ifu_fetch_data[127:0]), .dout(q1[127:0])); - rvdffe #(128) q0ff (.*, .en(qwen[0]), .din(ifu_fetch_data[127:0]), .dout(q0[127:0])); + rvdffe #(128) q0ff (.*, .en(qwen[0]), .din(ifu_fetch_data[127:0]), .dout(q0[127:0])); assign {q1eff[127:0],q0eff[127:0]} = (({256{qren[0]}} & {q1[127:0],q0[127:0]}) | ({256{qren[1]}} & {q2[127:0],q1[127:0]}) | ({256{qren[2]}} & {q0[127:0],q2[127:0]})); - + assign q0final[127:0] = (({128{q0sel[0]}} & { q0eff[8*16-1:16*0]}) | - ({128{q0sel[1]}} & {{16*1{1'b0}},q0eff[8*16-1:16*1]}) | + ({128{q0sel[1]}} & {{16*1{1'b0}},q0eff[8*16-1:16*1]}) | ({128{q0sel[2]}} & {{16*2{1'b0}},q0eff[8*16-1:16*2]}) | ({128{q0sel[3]}} & {{16*3{1'b0}},q0eff[8*16-1:16*3]}) | ({128{q0sel[4]}} & {{16*4{1'b0}},q0eff[8*16-1:16*4]}) | ({128{q0sel[5]}} & {{16*5{1'b0}},q0eff[8*16-1:16*5]}) | ({128{q0sel[6]}} & {{16*6{1'b0}},q0eff[8*16-1:16*6]}) | - ({128{q0sel[7]}} & {{16*7{1'b0}},q0eff[8*16-1:16*7]})); - + ({128{q0sel[7]}} & {{16*7{1'b0}},q0eff[8*16-1:16*7]})); + assign q1final[127:0] = (({128{q1sel[0]}} & { q1eff[8*16-1:16*0]}) | - ({128{q1sel[1]}} & {{16*1{1'b0}},q1eff[8*16-1:16*1]}) | + ({128{q1sel[1]}} & {{16*1{1'b0}},q1eff[8*16-1:16*1]}) | ({128{q1sel[2]}} & {{16*2{1'b0}},q1eff[8*16-1:16*2]}) | ({128{q1sel[3]}} & {{16*3{1'b0}},q1eff[8*16-1:16*3]}) | ({128{q1sel[4]}} & {{16*4{1'b0}},q1eff[8*16-1:16*4]}) | ({128{q1sel[5]}} & {{16*5{1'b0}},q1eff[8*16-1:16*5]}) | ({128{q1sel[6]}} & {{16*6{1'b0}},q1eff[8*16-1:16*6]}) | - ({128{q1sel[7]}} & {{16*7{1'b0}},q1eff[8*16-1:16*7]})); - + ({128{q1sel[7]}} & {{16*7{1'b0}},q1eff[8*16-1:16*7]})); - assign aligndata[63:0] = ({64{(f0val[3])}} & {q0final[4*16-1:0]}) | + + assign aligndata[63:0] = ({64{(f0val[3])}} & {q0final[4*16-1:0]}) | ({64{(f0val[2]&~f0val[3])}} & {q1final[1*16-1:0],q0final[3*16-1:0]}) | ({64{(f0val[1]&~f0val[2])}} & {q1final[2*16-1:0],q0final[2*16-1:0]}) | - ({64{(f0val[0]&~f0val[1])}} & {q1final[3*16-1:0],q0final[1*16-1:0]}); - - assign alignval[3:0] = ({4{(f0val[3])}} & 4'b1111) | + ({64{(f0val[0]&~f0val[1])}} & {q1final[3*16-1:0],q0final[1*16-1:0]}); + + assign alignval[3:0] = ({4{(f0val[3])}} & 4'b1111) | ({4{(f0val[2]&~f0val[3])}} & {f1val[0],3'b111}) | ({4{(f0val[1]&~f0val[2])}} & {f1val[1:0],2'b11}) | - ({4{(f0val[0]&~f0val[1])}} & {f1val[2:0],1'b1}); + ({4{(f0val[0]&~f0val[1])}} & {f1val[2:0],1'b1}); - assign alignicaf[3:0] = ({4{(f0val[3])}} & {4{f0icaf}}) | + assign alignicaf[3:0] = ({4{(f0val[3])}} & {4{f0icaf}}) | ({4{(f0val[2]&~f0val[3])}} & {{1{f1icaf}},{3{f0icaf}}}) | ({4{(f0val[1]&~f0val[2])}} & {{2{f1icaf}},{2{f0icaf}}}) | - ({4{(f0val[0]&~f0val[1])}} & {{3{f1icaf}},{1{f0icaf}}}); + ({4{(f0val[0]&~f0val[1])}} & {{3{f1icaf}},{1{f0icaf}}}); - assign alignsbecc[3:0] = ({4{(f0val[3])}} & {4{f0sbecc}}) | + assign alignsbecc[3:0] = ({4{(f0val[3])}} & {4{f0sbecc}}) | ({4{(f0val[2]&~f0val[3])}} & {{1{f1sbecc}},{3{f0sbecc}}}) | ({4{(f0val[1]&~f0val[2])}} & {{2{f1sbecc}},{2{f0sbecc}}}) | - ({4{(f0val[0]&~f0val[1])}} & {{3{f1sbecc}},{1{f0sbecc}}}); + ({4{(f0val[0]&~f0val[1])}} & {{3{f1sbecc}},{1{f0sbecc}}}); - assign aligndbecc[3:0] = ({4{(f0val[3])}} & {4{f0dbecc}}) | + assign aligndbecc[3:0] = ({4{(f0val[3])}} & {4{f0dbecc}}) | ({4{(f0val[2]&~f0val[3])}} & {{1{f1dbecc}},{3{f0dbecc}}}) | ({4{(f0val[1]&~f0val[2])}} & {{2{f1dbecc}},{2{f0dbecc}}}) | - ({4{(f0val[0]&~f0val[1])}} & {{3{f1dbecc}},{1{f0dbecc}}}); + ({4{(f0val[0]&~f0val[1])}} & {{3{f1dbecc}},{1{f0dbecc}}}); // for branch prediction assign alignbrend[3:0] = ({4{(f0val[3])}} & f0brend[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1brend[0],f0brend[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1brend[0],f0brend[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1brend[1:0],f0brend[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1brend[2:0],f0brend[0]}); - + assign alignpc4[3:0] = ({4{(f0val[3])}} & f0pc4[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1pc4[0],f0pc4[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1pc4[0],f0pc4[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1pc4[1:0],f0pc4[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1pc4[2:0],f0pc4[0]}); `ifdef RV_ICACHE_ECC assign alignecc[19:0] = ({20{(f0val[3])}} & q0eccfinal[19:0]) | - ({20{(f0val[2]&~f0val[3])}} & {q1eccfinal[4:0], q0eccfinal[14:0]}) | + ({20{(f0val[2]&~f0val[3])}} & {q1eccfinal[4:0], q0eccfinal[14:0]}) | ({20{(f0val[1]&~f0val[2])}} & {q1eccfinal[9:0], q0eccfinal[9:0]}) | ({20{(f0val[0]&~f0val[1])}} & {q1eccfinal[14:0],q0eccfinal[4:0]}); -`else +`else assign alignparity[3:0] = ({4{(f0val[3])}} & q0parityfinal[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {q1parityfinal[0], q0parityfinal[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {q1parityfinal[0], q0parityfinal[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {q1parityfinal[1:0],q0parityfinal[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {q1parityfinal[2:0],q0parityfinal[0]}); `endif - assign aligntagperr[3:0] = ({4{(f0val[3])}} & {4{f0perr}}) | + assign aligntagperr[3:0] = ({4{(f0val[3])}} & {4{f0perr}}) | ({4{(f0val[2]&~f0val[3])}} & {{1{f1perr}},{3{f0perr}}}) | ({4{(f0val[1]&~f0val[2])}} & {{2{f1perr}},{2{f0perr}}}) | - ({4{(f0val[0]&~f0val[1])}} & {{3{f1perr}},{1{f0perr}}}); - - assign alignicfetch[3:0] = ({4{(f0val[3])}} & {4{f0icfetch}}) | + ({4{(f0val[0]&~f0val[1])}} & {{3{f1perr}},{1{f0perr}}}); + + assign alignicfetch[3:0] = ({4{(f0val[3])}} & {4{f0icfetch}}) | ({4{(f0val[2]&~f0val[3])}} & {{1{f1icfetch}},{3{f0icfetch}}}) | ({4{(f0val[1]&~f0val[2])}} & {{2{f1icfetch}},{2{f0icfetch}}}) | - ({4{(f0val[0]&~f0val[1])}} & {{3{f1icfetch}},{1{f0icfetch}}}); - - + ({4{(f0val[0]&~f0val[1])}} & {{3{f1icfetch}},{1{f0icfetch}}}); + + assign alignret[3:0] = ({4{(f0val[3])}} & f0ret[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1ret[0],f0ret[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1ret[0],f0ret[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1ret[1:0],f0ret[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1ret[2:0],f0ret[0]}); - + `ifdef RV_BTB_48 logic [3:0] f0way_b0, f0way_b1, alignway_b0, alignway_b1; @@ -777,41 +777,41 @@ module ifu_aln_ctl assign f1way_b1[2:0] = {f1way[2][1], f1way[1][1], f1way[0][1]}; assign alignway_b0[3:0] = ({4{(f0val[3])}} & f0way_b0[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1way_b0[0], f0way_b0[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1way_b0[0], f0way_b0[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1way_b0[1:0],f0way_b0[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1way_b0[2:0],f0way_b0[0]}); assign alignway_b1[3:0] = ({4{(f0val[3])}} & f0way_b1[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1way_b1[0], f0way_b1[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1way_b1[0], f0way_b1[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1way_b1[1:0],f0way_b1[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1way_b1[2:0],f0way_b1[0]}); `else assign alignway[3:0] = ({4{(f0val[3])}} & f0way[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1way[0],f0way[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1way[0],f0way[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1way[1:0],f0way[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1way[2:0],f0way[0]}); `endif assign alignhist1[3:0] = ({4{(f0val[3])}} & f0hist1[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1hist1[0],f0hist1[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1hist1[0],f0hist1[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1hist1[1:0],f0hist1[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1hist1[2:0],f0hist1[0]}); assign alignhist0[3:0] = ({4{(f0val[3])}} & f0hist0[3:0]) | - ({4{(f0val[2]&~f0val[3])}} & {f1hist0[0],f0hist0[2:0]}) | + ({4{(f0val[2]&~f0val[3])}} & {f1hist0[0],f0hist0[2:0]}) | ({4{(f0val[1]&~f0val[2])}} & {f1hist0[1:0],f0hist0[1:0]}) | ({4{(f0val[0]&~f0val[1])}} & {f1hist0[2:0],f0hist0[0]}); assign alignfromf1[3:1] = ({3{(f0val[3])}} & 3'b0) | - ({3{(f0val[2]&~f0val[3])}} & {1'b1,2'b0}) | + ({3{(f0val[2]&~f0val[3])}} & {1'b1,2'b0}) | ({3{(f0val[1]&~f0val[2])}} & {2'b11,1'b0}) | ({3{(f0val[0]&~f0val[1])}} & {3'b111}); - - assign { secondpc[31:1], + + assign { secondpc[31:1], thirdpc[31:1], fourthpc[31:1] } = ({3*31{(f0val[3])}} & {f0pc_plus1[31:1], f0pc_plus2[31:1], f0pc_plus3[31:1]}) | - ({3*31{(f0val[2]&~f0val[3])}} & {f0pc_plus1[31:1], f0pc_plus2[31:1], f1pc[31:1]}) | - ({3*31{(f0val[1]&~f0val[2])}} & {f0pc_plus1[31:1], f1pc[31:1], f1pc_plus1[31:1]}) | - ({3*31{(f0val[0]&~f0val[1])}} & {f1pc[31:1], f1pc_plus1[31:1], f1pc_plus2[31:1]}); + ({3*31{(f0val[2]&~f0val[3])}} & {f0pc_plus1[31:1], f0pc_plus2[31:1], f1pc[31:1]}) | + ({3*31{(f0val[1]&~f0val[2])}} & {f0pc_plus1[31:1], f1pc[31:1], f1pc_plus1[31:1]}) | + ({3*31{(f0val[0]&~f0val[1])}} & {f1pc[31:1], f1pc_plus1[31:1], f1pc_plus2[31:1]}); assign ifu_i0_pc[31:1] = f0pc[31:1]; @@ -819,8 +819,8 @@ module ifu_aln_ctl assign firstpc[31:1] = f0pc[31:1]; assign ifu_i1_pc[31:1] = (first2B) ? secondpc[31:1] : thirdpc[31:1]; - - + + assign ifu_i0_pc4 = first4B; assign ifu_i1_pc4 = (first2B & second4B) | @@ -835,7 +835,7 @@ module ifu_aln_ctl logic [3:0] ic_single_ecc_error; logic [3:0] ic_double_ecc_error; logic [3:0] aligneccerr; - + for (genvar i=0; i < 4 ; i++) begin : ic_ecc_error rvecc_decode ecc_decode ( .en(~dec_tlu_core_ecc_disable), @@ -852,9 +852,9 @@ module ifu_aln_ctl assign aligneccerr[i] = ic_single_ecc_error[i] | ic_double_ecc_error[i]; assign aligndataperr[i] = aligneccerr[i] ; end // block: ic_ecc_error - + `else // !`ifdef RV_ICACHE_ECC - + for (genvar i=0; i<4 ; i++) begin : ic_par_error rveven_paritycheck pchk ( .data_in(aligndata[16*(i+1)-1: 16*i]), @@ -862,7 +862,7 @@ module ifu_aln_ctl .parity_err(aligndataperr[i]) ); end - + `endif // !`ifdef RV_ICACHE_ECC @@ -870,10 +870,10 @@ module ifu_aln_ctl assign ifu_i0_cinst[15:0] = aligndata[15:0]; assign ifu_i1_cinst[15:0] = (first4B) ? aligndata[47:32] : aligndata[31:16]; // end trace - - + + // check on 16B boundaries - // + // assign first4B = aligndata[16*0+1:16*0] == 2'b11; assign first2B = ~first4B; @@ -896,9 +896,9 @@ module ifu_aln_ctl (first2B & alignicaf[0])) & ~exu_flush_final; - + assign icaf_eff[3:1] = alignicaf[3:1] | aligndbecc[3:1]; - + assign ifu_i0_icaf_f1 = first4B & icaf_eff[1] & alignfromf1[1]; assign ifu_i1_icaf = ((first4B & third4B & (|alignicaf[3:2])) | @@ -913,9 +913,9 @@ module ifu_aln_ctl // inst parity error on any byte of inst results in parity error for the inst - + assign alignfinalperr[3:0] = (aligntagperr[3:0] | aligndataperr[3:0]) & alignicfetch[3:0]; - + assign ifu_i0_perr = ((first4B & (|alignfinalperr[1:0])) | (first2B & alignfinalperr[0])) & ~exu_flush_final; @@ -926,7 +926,7 @@ module ifu_aln_ctl assign ifu_i0_sbecc = ((first4B & (|alignsbecc[1:0])) | (first2B & alignsbecc[0])) & ~exu_flush_final; - + assign ifu_i1_sbecc = ((first4B & third4B & (|alignsbecc[3:2])) | (first4B & third2B & alignsbecc[2]) | (first2B & second4B & (|alignsbecc[2:1])) | @@ -944,7 +944,7 @@ module ifu_aln_ctl // parity error is orthogonal to single-bit ecc error; icache vs iccm logic [2:0] alignicerr; - + assign alignicerr[2:0] = alignfinalperr[2:0] | alignsbecc[2:0]; assign ifu_icache_error_index[16:2] = (alignicerr[0]) ? firstpc[16:2] : @@ -954,24 +954,24 @@ module ifu_aln_ctl assign ifu_icache_error_val = (i0_shift & ifu_i0_perr) | (i1_shift & ifu_i1_perr & ~ifu_i0_sbecc); - + assign ifu_icache_sb_error_val = (i0_shift & ifu_i0_sbecc) | (i1_shift & ifu_i1_sbecc & ~ifu_i0_perr); `ifdef ASSERT_ON - assert_ifu_icache_parity_with_sbecc_error: assert #0 ($onehot0({ifu_icache_error_val,ifu_icache_sb_error_val})); -`endif + assert_ifu_icache_parity_with_sbecc_error: assert #0 ($onehot0({ifu_icache_error_val,ifu_icache_sb_error_val})); +`endif // big endian 4B instructions assign ifirst[31:0] = aligndata[2*16-1:0*16]; assign isecond[31:0] = aligndata[3*16-1:1*16]; - + assign ithird[31:0] = aligndata[4*16-1:2*16]; - - - + + + assign ifu_i0_instr[31:0] = ({32{first4B}} & ifirst[31:0]) | ({32{first2B}} & uncompress0[31:0]); @@ -989,7 +989,7 @@ module ifu_aln_ctl rvbtb_addr_hash fourthhash(.pc(fourthpc[31:1]), .hash(fourthpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO])); logic [`RV_BTB_BTAG_SIZE-1:0] firstbrtag_hash, secondbrtag_hash, thirdbrtag_hash, fourthbrtag_hash; - + rvbtb_tag_hash first_brhash(.pc(firstpc[31:1]), .hash(firstbrtag_hash[`RV_BTB_BTAG_SIZE-1:0])); rvbtb_tag_hash second_brhash(.pc(secondpc[31:1]), .hash(secondbrtag_hash[`RV_BTB_BTAG_SIZE-1:0])); rvbtb_tag_hash third_brhash(.pc(thirdpc[31:1]), .hash(thirdbrtag_hash[`RV_BTB_BTAG_SIZE-1:0])); @@ -997,41 +997,41 @@ module ifu_aln_ctl // start_indexing - you want pc to be based on where the end of branch is prediction // normal indexing pc based that's incorrect now for pc4 cases it's pc4 + 2 - + always_comb begin i0_brp = '0; i0_br_start_error = (first4B & alignval[1] & alignbrend[0]); - i0_brp.valid = (first2B & alignbrend[0]) | + i0_brp.valid = (first2B & alignbrend[0]) | (first4B & alignbrend[1]) | i0_br_start_error; - - i0_brp_pc4 = (first2B & alignpc4[0]) | + + i0_brp_pc4 = (first2B & alignpc4[0]) | (first4B & alignpc4[1]); - i0_brp.ret = (first2B & alignret[0]) | + i0_brp.ret = (first2B & alignret[0]) | (first4B & alignret[1]); `ifdef RV_BTB_48 i0_brp.way = (first2B | alignbrend[0]) ? {alignway_b1[0], alignway_b0[0]} : {alignway_b1[1], alignway_b0[1]}; `else i0_brp.way = (first2B | alignbrend[0]) ? alignway[0] : alignway[1]; -`endif +`endif i0_brp.hist[1] = (first2B & alignhist1[0]) | (first4B & alignhist1[1]); - + i0_brp.hist[0] = (first2B & alignhist0[0]) | (first4B & alignhist0[1]); i0_ends_f1 = (first4B & alignfromf1[1]); - + i0_brp.toffset[11:0] = (i0_ends_f1) ? f1poffset[11:0] : f0poffset[11:0]; i0_brp.fghr[`RV_BHT_GHR_RANGE] = (i0_ends_f1) ? f1fghr[`RV_BHT_GHR_RANGE] : f0fghr[`RV_BHT_GHR_RANGE]; - i0_brp.prett[31:1] = (i0_ends_f1) ? f1prett[31:1] : f0prett[31:1]; + i0_brp.prett[31:1] = (i0_ends_f1) ? f1prett[31:1] : f0prett[31:1]; i0_brp.br_start_error = i0_br_start_error; @@ -1043,11 +1043,11 @@ module ifu_aln_ctl i0_brp.bank[1:0] = (first2B | alignbrend[0]) ? firstpc[3:2] : secondpc[3:2]; - - + + i0_brp.br_error = (i0_brp.valid & i0_brp_pc4 & first2B) | (i0_brp.valid & ~i0_brp_pc4 & first4B); - + i1_brp = '0; i1_br_start_error = (first2B & second4B & alignval[2] & alignbrend[1]) | @@ -1063,7 +1063,7 @@ module ifu_aln_ctl (first4B & third4B & alignpc4[3]) | (first2B & second2B & alignpc4[1]) | (first2B & second4B & alignpc4[2]); - + i1_brp.ret = (first4B & third2B & alignret[2]) | (first4B & third4B & alignret[3]) | (first2B & second2B & alignret[1]) | @@ -1071,18 +1071,18 @@ module ifu_aln_ctl `ifdef RV_BTB_48 i1_brp.way = ({2{first4B & third2B }} & {alignway_b1[2], alignway_b0[2]} ) | ({2{first4B & third4B & alignbrend[2] }} & {alignway_b1[2], alignway_b0[2]} ) | - ({2{first4B & third4B & ~alignbrend[2] }} & {alignway_b1[3], alignway_b0[3]} ) | + ({2{first4B & third4B & ~alignbrend[2] }} & {alignway_b1[3], alignway_b0[3]} ) | ({2{first2B & second2B }} & {alignway_b1[1], alignway_b0[1]} ) | ({2{first2B & second4B & alignbrend[1]}} & {alignway_b1[1], alignway_b0[1]} ) | ({2{first2B & second4B & ~alignbrend[1]}} & {alignway_b1[2], alignway_b0[2]} ); -`else +`else i1_brp.way = (first4B & third2B & alignway[2] ) | (first4B & third4B & alignbrend[2] & alignway[2] ) | - (first4B & third4B & ~alignbrend[2] & alignway[3] ) | + (first4B & third4B & ~alignbrend[2] & alignway[3] ) | (first2B & second2B & alignway[1] ) | (first2B & second4B & alignbrend[1] & alignway[1] ) | (first2B & second4B & ~alignbrend[1] & alignway[2] ); -`endif +`endif i1_brp.hist[1] = (first4B & third2B & alignhist1[2]) | (first4B & third4B & alignhist1[3]) | (first2B & second2B & alignhist1[1]) | @@ -1102,29 +1102,29 @@ module ifu_aln_ctl i1_brp.fghr[`RV_BHT_GHR_RANGE] = (i1_ends_f1) ? f1fghr[`RV_BHT_GHR_RANGE] : f0fghr[`RV_BHT_GHR_RANGE]; - i1_brp.prett[31:1] = (i1_ends_f1) ? f1prett[31:1] : f0prett[31:1]; - + i1_brp.prett[31:1] = (i1_ends_f1) ? f1prett[31:1] : f0prett[31:1]; + i1_brp.br_start_error = i1_br_start_error; `define RV_BTB_RANGE `RV_BTB_ADDR_HI-`RV_BTB_ADDR_LO+1 - + i1_brp.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = ({`RV_BTB_RANGE{first4B & third2B }} & thirdpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | ({`RV_BTB_RANGE{first4B & third4B & alignbrend[2] }} & thirdpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | - ({`RV_BTB_RANGE{first4B & third4B & ~alignbrend[2] }} & fourthpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | + ({`RV_BTB_RANGE{first4B & third4B & ~alignbrend[2] }} & fourthpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | ({`RV_BTB_RANGE{first2B & second2B}} & secondpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | ({`RV_BTB_RANGE{first2B & second4B & alignbrend[1]}} & secondpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ) | ({`RV_BTB_RANGE{first2B & second4B & ~alignbrend[1]}} & thirdpc_hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] ); - + i1_brp.btag[`RV_BTB_BTAG_SIZE-1:0] = ({`RV_BTB_BTAG_SIZE{first4B & third2B }} & thirdbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | ({`RV_BTB_BTAG_SIZE{first4B & third4B & alignbrend[2] }} & thirdbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | - ({`RV_BTB_BTAG_SIZE{first4B & third4B & ~alignbrend[2] }} & fourthbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | + ({`RV_BTB_BTAG_SIZE{first4B & third4B & ~alignbrend[2] }} & fourthbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | ({`RV_BTB_BTAG_SIZE{first2B & second2B}} & secondbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | ({`RV_BTB_BTAG_SIZE{first2B & second4B & alignbrend[1]}} & secondbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ) | ({`RV_BTB_BTAG_SIZE{first2B & second4B & ~alignbrend[1]}} & thirdbrtag_hash[`RV_BTB_BTAG_SIZE-1:0] ); i1_brp.bank[1:0] = ({2{first4B & third2B }} & thirdpc[3:2] ) | ({2{first4B & third4B & alignbrend[2] }} & thirdpc[3:2] ) | - ({2{first4B & third4B & ~alignbrend[2] }} & fourthpc[3:2] ) | + ({2{first4B & third4B & ~alignbrend[2] }} & fourthpc[3:2] ) | ({2{first2B & second2B}} & secondpc[3:2] ) | ({2{first2B & second4B & alignbrend[1]}} & secondpc[3:2] ) | ({2{first2B & second4B & ~alignbrend[1]}} & thirdpc[3:2] ); @@ -1133,11 +1133,11 @@ module ifu_aln_ctl (i1_brp.valid & ~i1_brp_pc4 & first4B & third4B ) | (i1_brp.valid & i1_brp_pc4 & first2B & second2B) | (i1_brp.valid & ~i1_brp_pc4 & first2B & second4B); - end + end // figure out 2B illegal insts - - assign i0_illegal = (first2B & ~first_legal); + + assign i0_illegal = (first2B & ~first_legal); assign i1_illegal = (first2B & second2B & ~second_legal) | (first4B & third2B & ~third_legal); @@ -1145,25 +1145,25 @@ module ifu_aln_ctl assign shift_illegal = (i0_shift & i0_illegal) | (i1_shift & i1_illegal); - assign illegal_inst[15:0] = (first2B & ~first_legal) ? aligndata[1*16-1:0*16] : + assign illegal_inst[15:0] = (first2B & ~first_legal) ? aligndata[1*16-1:0*16] : ((first2B & second2B & ~second_legal) ? aligndata[2*16-1:1*16] : aligndata[3*16-1:2*16]); assign illegal_inst_en = shift_illegal & ~illegal_lockout; - + rvdffe #(16) illegal_any_ff (.*, .en(illegal_inst_en), .din(illegal_inst[15:0]), .dout(ifu_illegal_inst[15:0])); assign illegal_lockout_in = (shift_illegal | illegal_lockout) & ~exu_flush_final; - + rvdff #(1) illegal_lockout_any_ff (.*, .clk(active_clk), .din(illegal_lockout_in), .dout(illegal_lockout)); - - + + // decompress ifu_compress_ctl compress0 (.din(aligndata[16*1-1:0*16]), .dout(uncompress0[31:0]), .legal(first_legal) ); ifu_compress_ctl compress1 (.din(aligndata[16*2-1:1*16]), .dout(uncompress1[31:0]), .legal(second_legal) ); - - ifu_compress_ctl compress2 (.din(aligndata[16*3-1:2*16]), .dout(uncompress2[31:0]), .legal(third_legal) ); + + ifu_compress_ctl compress2 (.din(aligndata[16*3-1:2*16]), .dout(uncompress2[31:0]), .legal(third_legal) ); @@ -1171,7 +1171,7 @@ module ifu_aln_ctl assign i1_shift = ifu_i1_valid & ibuffer_room2_more; - if (DEC_INSTBUF_DEPTH==4) begin + if (DEC_INSTBUF_DEPTH==4) begin assign ibuffer_room1_more = ~dec_ib3_valid_d; assign ibuffer_room2_more = ~dec_ib2_valid_d; end @@ -1179,15 +1179,15 @@ module ifu_aln_ctl assign ibuffer_room1_more = ~dec_ib0_valid_eff_d | ~dec_ib1_valid_eff_d; assign ibuffer_room2_more = ~dec_ib0_valid_eff_d & ~dec_ib1_valid_eff_d; end - - + + assign ifu_pmu_instr_aligned[1:0] = { i1_shift, i0_shift }; assign ifu_pmu_align_stall = ifu_i0_valid & ~ibuffer_room1_more; - + // compute how many bytes are being shifted from f0 - + // assign shift_0B = ~i0_shift; assign shift_2B = i0_shift & ~i1_shift & first2B; @@ -1202,24 +1202,24 @@ module ifu_aln_ctl assign shift_8B = i0_shift & i1_shift & first4B & third4B; // exact equations for the queue logic - assign f0_shift_2B = (shift_2B & f0val[0]) | + assign f0_shift_2B = (shift_2B & f0val[0]) | ((shift_4B | shift_6B | shift_8B) & f0val[0] & ~f0val[1]); - assign f0_shift_4B = (shift_4B & f0val[1]) | + assign f0_shift_4B = (shift_4B & f0val[1]) | ((shift_6B & shift_8B) & f0val[1] & ~f0val[2]); - - + + assign f0_shift_6B = (shift_6B & f0val[2]) | (shift_8B & f0val[2] & ~f0val[3]); - + assign f0_shift_8B = shift_8B & f0val[3]; - - - + + + // f0 valid states - // + // // 11111111 - // 11111110 + // 11111110 // 11111100 // 11111000 // 11110000 @@ -1227,20 +1227,20 @@ module ifu_aln_ctl // 11100000 // 11000000 // 10000000 - // 00000000 - + // 00000000 + // assign f1_shift_0B = shift_0B; - + assign f1_shift_2B = (f0val[2] & ~f0val[3] & shift_8B) | (f0val[1] & ~f0val[2] & shift_6B) | (f0val[0] & ~f0val[1] & shift_4B); - + assign f1_shift_4B = (f0val[1] & ~f0val[2] & shift_8B) | (f0val[0] & ~f0val[1] & shift_6B); - + assign f1_shift_6B = (f0val[0] & ~f0val[1] & shift_8B); - - -endmodule + + +endmodule diff --git a/design/ifu/ifu_bp_ctl.sv b/design/ifu/ifu_bp_ctl.sv index 4bd8a22..c6f7b16 100644 --- a/design/ifu/ifu_bp_ctl.sv +++ b/design/ifu/ifu_bp_ctl.sv @@ -27,7 +27,7 @@ module ifu_bp_ctl import swerv_types::*; ( - + input logic clk, input logic active_clk, input logic clk_override, @@ -42,19 +42,19 @@ module ifu_bp_ctl input br_tlu_pkt_t dec_tlu_br0_wb_pkt, // BP commit update packet, includes errors input br_tlu_pkt_t dec_tlu_br1_wb_pkt, // BP commit update packet, includes errors - + 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 - input logic dec_tlu_bpred_disable, // disable all branch prediction - + input logic dec_tlu_bpred_disable, // disable all branch prediction + input logic exu_i0_br_ret_e4, // EX4 ret stack update input logic exu_i1_br_ret_e4, // EX4 ret stack update input logic exu_i0_br_call_e4, // EX4 ret stack update input logic exu_i1_br_call_e4, // EX4 ret stack update input predict_pkt_t exu_mp_pkt, // mispredict packet - + input rets_pkt_t exu_rets_e1_pkt, // EX1 rets packet input rets_pkt_t exu_rets_e4_pkt, // EX4 rets packet @@ -69,7 +69,7 @@ module ifu_bp_ctl input logic exu_flush_final, // all flushes input logic exu_flush_upper_e2, // flush upper, either i0 or i1, cp EX1 RS to F RS - + output logic ifu_bp_kill_next_f2, // kill next fetch, taken target found output logic [31:1] ifu_bp_btb_target_f2, // predicted target PC output logic [7:1] ifu_bp_inst_mask_f2, // tell ic which valids to kill because of a taken branch, right justified @@ -104,7 +104,7 @@ module ifu_bp_ctl localparam NUM_BHT_LOOP_INNER_HI = (`RV_BHT_ARRAY_DEPTH > 16 ) ?`RV_BHT_ADDR_LO+3 : `RV_BHT_ADDR_HI; localparam NUM_BHT_LOOP_OUTER_LO = (`RV_BHT_ARRAY_DEPTH > 16 ) ?`RV_BHT_ADDR_LO+4 : `RV_BHT_ADDR_LO; localparam BHT_NO_ADDR_MATCH = ( `RV_BHT_ARRAY_DEPTH <= 16 ); - + logic exu_mp_valid_write; logic exu_mp_ataken; logic exu_mp_valid; // conditional branch mispredict @@ -126,7 +126,7 @@ module ifu_bp_ctl logic dec_tlu_br0_error_wb; // error; invalidate bank logic dec_tlu_br0_start_error_wb; // error; invalidate all 4 banks in fg logic [`RV_BHT_GHR_RANGE] dec_tlu_br0_fghr_wb; - + logic dec_tlu_br1_v_wb; // WB stage history update logic [1:0] dec_tlu_br1_hist_wb; // new history logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] dec_tlu_br1_addr_wb; // addr @@ -138,7 +138,7 @@ module ifu_bp_ctl logic [3:0] use_mp_way; logic [`RV_RET_STACK_SIZE-1:0][31:1] rets_out, rets_in, e1_rets_out, e1_rets_in, e4_rets_out, e4_rets_in; logic [`RV_RET_STACK_SIZE-1:0] rsenable; - + logic [11:0] btb_rd_tgt_f2; logic btb_rd_pc4_f2, btb_rd_boffset_f2, btb_rd_call_f2, btb_rd_ret_f2; @@ -152,7 +152,7 @@ module ifu_bp_ctl logic [16+`RV_BTB_BTAG_SIZE:0] btb_wr_data; logic [3:0] btb_wr_en_way0, btb_wr_en_way1; - + logic dec_tlu_error_wb, dec_tlu_all_banks_error_wb, btb_valid, dec_tlu_br0_middle_wb, dec_tlu_br1_middle_wb; logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] btb_error_addr_wb; logic [1:0] dec_tlu_error_bank_wb; @@ -162,11 +162,11 @@ module ifu_bp_ctl logic [3:0] branch_error_bank_conflict_f1, branch_error_bank_conflict_f2; logic [`RV_BHT_GHR_RANGE] merged_ghr, fghr_ns, fghr; logic [3:0] num_valids; - logic [LRU_SIZE-1:0] btb_lru_b0_f, btb_lru_b0_hold, btb_lru_b0_ns, btb_lru_b1_f, btb_lru_b1_hold, btb_lru_b1_ns, - btb_lru_b2_f, btb_lru_b2_hold, btb_lru_b2_ns, btb_lru_b3_f, btb_lru_b3_hold, btb_lru_b3_ns, + logic [LRU_SIZE-1:0] btb_lru_b0_f, btb_lru_b0_hold, btb_lru_b0_ns, btb_lru_b1_f, btb_lru_b1_hold, btb_lru_b1_ns, + btb_lru_b2_f, btb_lru_b2_hold, btb_lru_b2_ns, btb_lru_b3_f, btb_lru_b3_hold, btb_lru_b3_ns, fetch_wrindex_dec, fetch_wrlru_b0, fetch_wrlru_b1, fetch_wrlru_b2, fetch_wrlru_b3, mp_wrindex_dec, mp_wrlru_b0, mp_wrlru_b1, mp_wrlru_b2, mp_wrlru_b3; - logic [3:0] btb_lru_rd_f2, mp_bank_decoded, mp_bank_decoded_f, lru_update_valid_f2; + logic [3:0] btb_lru_rd_f2, mp_bank_decoded, mp_bank_decoded_f, lru_update_valid_f2; logic [3:0] tag_match_way0_f2, tag_match_way1_f2; logic [7:0] way_raw, bht_dir_f2, btb_sel_f2, wayhit_f2; logic [7:0] btb_sel_mask_f2, bht_valid_f2, bht_force_taken_f2; @@ -177,7 +177,7 @@ module ifu_bp_ctl logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank1_rd_data_way0_out ; logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank2_rd_data_way0_out ; logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank3_rd_data_way0_out ; - + logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank0_rd_data_way1_out ; logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank1_rd_data_way1_out ; logic [LRU_SIZE-1:0][16+`RV_BTB_BTAG_SIZE:0] btb_bank2_rd_data_way1_out ; @@ -193,7 +193,7 @@ module ifu_bp_ctl logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank2_rd_data_way1_f2_in ; logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank3_rd_data_way1_f2_in ; - + logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank0_rd_data_way0_f2 ; logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank1_rd_data_way0_f2 ; logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank2_rd_data_way0_f2 ; @@ -225,10 +225,10 @@ module ifu_bp_ctl logic [3:0] btb_wr_en_way2, tag_match_way2_f2, fetch_lru_bank_hit_f2; logic [7:0] tag_match_way2_expanded_f2; - logic [1:0] exu_mp_way, exu_mp_way_f, dec_tlu_br0_way_wb, dec_tlu_br1_way_wb, dec_tlu_way_wb, dec_tlu_way_wb_f; + logic [1:0] exu_mp_way, exu_mp_way_f, dec_tlu_br0_way_wb, dec_tlu_br1_way_wb, dec_tlu_way_wb, dec_tlu_way_wb_f; `else // !`ifdef RV_BTB_48 - logic exu_mp_way, exu_mp_way_f, dec_tlu_br0_way_wb, dec_tlu_br1_way_wb, dec_tlu_way_wb, dec_tlu_way_wb_f; + logic exu_mp_way, exu_mp_way_f, dec_tlu_br0_way_wb, dec_tlu_br1_way_wb, dec_tlu_way_wb, dec_tlu_way_wb_f; `endif logic [16+`RV_BTB_BTAG_SIZE:0] btb_bank0e_rd_data_f2 ; @@ -244,15 +244,15 @@ module ifu_bp_ctl logic [7:0] tag_match_way0_expanded_f2, tag_match_way1_expanded_f2; - logic [1:0] bht_bank0_rd_data_f2 ; - logic [1:0] bht_bank1_rd_data_f2 ; - logic [1:0] bht_bank2_rd_data_f2 ; - logic [1:0] bht_bank3_rd_data_f2 ; - logic [1:0] bht_bank4_rd_data_f2 ; - logic [1:0] bht_bank5_rd_data_f2 ; - logic [1:0] bht_bank6_rd_data_f2 ; - logic [1:0] bht_bank7_rd_data_f2 ; - + logic [1:0] bht_bank0_rd_data_f2 ; + logic [1:0] bht_bank1_rd_data_f2 ; + logic [1:0] bht_bank2_rd_data_f2 ; + logic [1:0] bht_bank3_rd_data_f2 ; + logic [1:0] bht_bank4_rd_data_f2 ; + logic [1:0] bht_bank5_rd_data_f2 ; + logic [1:0] bht_bank6_rd_data_f2 ; + logic [1:0] bht_bank7_rd_data_f2 ; + assign exu_mp_valid = exu_mp_pkt.misp & ~leak_one_f2; // conditional branch mispredict assign exu_mp_boffset = exu_mp_pkt.boffset; // branch offset assign exu_mp_pc4 = exu_mp_pkt.pc4; // branch is a 4B inst @@ -267,8 +267,8 @@ module ifu_bp_ctl assign exu_mp_btag[`RV_BTB_BTAG_SIZE-1:0] = exu_mp_pkt.btag[`RV_BTB_BTAG_SIZE-1:0] ; // branch tag assign exu_mp_fghr[`RV_BHT_GHR_RANGE] = exu_mp_pkt.fghr[`RV_BHT_GHR_RANGE] ; // original fetch ghr (for bht update) assign exu_mp_ataken = exu_mp_pkt.ataken; - - assign dec_tlu_br0_v_wb = dec_tlu_br0_wb_pkt.valid; + + assign dec_tlu_br0_v_wb = dec_tlu_br0_wb_pkt.valid; assign dec_tlu_br0_hist_wb[1:0] = dec_tlu_br0_wb_pkt.hist[1:0]; assign dec_tlu_br0_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = dec_tlu_br0_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; assign dec_tlu_br0_bank_wb[1:0] = dec_tlu_br0_wb_pkt.bank[1:0]; @@ -278,7 +278,7 @@ module ifu_bp_ctl assign dec_tlu_br0_start_error_wb = dec_tlu_br0_wb_pkt.br_start_error; assign dec_tlu_br0_fghr_wb[`RV_BHT_GHR_RANGE] = dec_tlu_br0_wb_pkt.fghr[`RV_BHT_GHR_RANGE]; - assign dec_tlu_br1_v_wb = dec_tlu_br1_wb_pkt.valid; + assign dec_tlu_br1_v_wb = dec_tlu_br1_wb_pkt.valid; assign dec_tlu_br1_hist_wb[1:0] = dec_tlu_br1_wb_pkt.hist[1:0]; assign dec_tlu_br1_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = dec_tlu_br1_wb_pkt.index[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; assign dec_tlu_br1_bank_wb[1:0] = dec_tlu_br1_wb_pkt.bank[1:0]; @@ -299,7 +299,7 @@ module ifu_bp_ctl rvbtb_addr_hash f1hash(.pc(ifc_fetch_addr_f1[31:1]), .hash(btb_rd_addr_f1[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO])); rvbtb_addr_hash f2hash(.pc(ifc_fetch_addr_f2[31:1]), .hash(btb_rd_addr_f2[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO])); - + // based on the fetch group offset(PC[3:2]) and direction bits, findfirst from fetchPC // this sel is zero/onehot @@ -309,18 +309,18 @@ module ifu_bp_ctl // .i 11 // .o 15 // .ilb ifc_fetch_addr_f2[3] ifc_fetch_addr_f2[2] ifc_fetch_addr_f2[1] bht_dir_f2[7] bht_dir_f2[6] bht_dir_f2[5] bht_dir_f2[4] bht_dir_f2[3] bht_dir_f2[2] bht_dir_f2[1] bht_dir_f2[0] -// .ob btb_sel_f2[7] btb_sel_f2[6] btb_sel_f2[5] btb_sel_f2[4] btb_sel_f2[3] btb_sel_f2[2] btb_sel_f2[1] btb_sel_f2[0] btb_vmask_raw_f2[7] btb_vmask_raw_f2[6] btb_vmask_raw_f2[5] btb_vmask_raw_f2[4] btb_vmask_raw_f2[3] btb_vmask_raw_f2[2] btb_vmask_raw_f2[1] +// .ob btb_sel_f2[7] btb_sel_f2[6] btb_sel_f2[5] btb_sel_f2[4] btb_sel_f2[3] btb_sel_f2[2] btb_sel_f2[1] btb_sel_f2[0] btb_vmask_raw_f2[7] btb_vmask_raw_f2[6] btb_vmask_raw_f2[5] btb_vmask_raw_f2[4] btb_vmask_raw_f2[3] btb_vmask_raw_f2[2] btb_vmask_raw_f2[1] // .type fr // ##faddress[3:1] dir[7:0] sel[7:0] mask[7:1] // 000 -------1 00000001 0000000 // 000 ------10 00000010 0000001 // 000 -----100 00000100 0000010 -// 000 ----1000 00001000 0000100 +// 000 ----1000 00001000 0000100 // 000 ---10000 00010000 0001000 // 000 --100000 00100000 0010000 // 000 -1000000 01000000 0100000 // 000 10000000 10000000 1000000 -// +// // 001 ------1- 00000010 0000000 // 001 -----10- 00000100 0000001 // 001 ----100- 00001000 0000010 @@ -328,32 +328,32 @@ module ifu_bp_ctl // 001 --10000- 00100000 0001000 // 001 -100000- 01000000 0010000 // 001 1000000- 10000000 0110000 -// +// // 010 -----1-- 00000100 0000000 // 010 ----10-- 00001000 0000001 // 010 ---100-- 00010000 0000010 // 010 --1000-- 00100000 0000100 // 010 -10000-- 01000000 0001000 // 010 100000-- 10000000 0010000 -// +// // 011 ----1--- 00001000 0000000 // 011 ---10--- 00010000 0000001 // 011 --100--- 00100000 0000010 // 011 -1000--- 01000000 0000100 // 011 10000--- 10000000 0001000 -// +// // 100 ---1---- 00010000 0000000 // 100 --10---- 00100000 0000001 // 100 -100---- 01000000 0000010 // 100 1000---- 10000000 0000100 -// +// // 101 --1----- 00100000 0000000 // 101 -10----- 01000000 0000001 // 101 100----- 10000000 0000010 -// +// // 110 -1------ 01000000 0000000 // 110 10------ 10000000 0000001 -// +// // 111 1------- 10000000 0000000 @@ -501,7 +501,7 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] // end of espresso generated equations - + logic[7:1] btb_vmask_f2; assign btb_vmask_f2[7:1] = {btb_vmask_raw_f2[7], |btb_vmask_raw_f2[7:6], @@ -510,15 +510,15 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] |btb_vmask_raw_f2[7:3], |btb_vmask_raw_f2[7:2], |btb_vmask_raw_f2[7:1]}; - + // Errors colliding with fetches must kill the btb/bht hit. assign branch_error_collision_f1 = dec_tlu_error_wb & (btb_error_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == btb_rd_addr_f1[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]); assign branch_error_bank_conflict_f1[3:0] = {4{branch_error_collision_f1}} & (decode2_4(dec_tlu_error_bank_wb[1:0]) | {4{dec_tlu_all_banks_error_wb}}); - - assign fetch_mp_collision_f1 = ( (exu_mp_btag[`RV_BTB_BTAG_SIZE-1:0] == fetch_rd_tag_f1[`RV_BTB_BTAG_SIZE-1:0]) & - exu_mp_valid & ifc_fetch_req_f1 & + + assign fetch_mp_collision_f1 = ( (exu_mp_btag[`RV_BTB_BTAG_SIZE-1:0] == fetch_rd_tag_f1[`RV_BTB_BTAG_SIZE-1:0]) & + exu_mp_valid & ifc_fetch_req_f1 & (exu_mp_addr[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == btb_rd_addr_f1[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]) ); // set on leak one, hold until next flush without leak one @@ -527,49 +527,49 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] `ifdef RV_BTB_48 rvdff #(15) coll_ff (.*, .clk(active_clk), `else - rvdff #(13) coll_ff (.*, .clk(active_clk), + rvdff #(13) coll_ff (.*, .clk(active_clk), `endif - .din({branch_error_bank_conflict_f1[3:0], fetch_mp_collision_f1, mp_bank_decoded[3:0], exu_mp_way, dec_tlu_way_wb, leak_one_f1, ifc_fetch_req_f1}), + .din({branch_error_bank_conflict_f1[3:0], fetch_mp_collision_f1, mp_bank_decoded[3:0], exu_mp_way, dec_tlu_way_wb, leak_one_f1, ifc_fetch_req_f1}), .dout({branch_error_bank_conflict_f2[3:0], fetch_mp_collision_f2, mp_bank_decoded_f[3:0], exu_mp_way_f, dec_tlu_way_wb_f, leak_one_f2, ifc_fetch_req_f2_raw})); `ifdef RV_BTB_48 - + // 2 -way SA, figure out the way hit and mux accordingly assign tag_match_way0_f2[3:0] = {btb_bank3_rd_data_way0_f2[BV] & (btb_bank3_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank2_rd_data_way0_f2[BV] & (btb_bank2_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank1_rd_data_way0_f2[BV] & (btb_bank1_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), - btb_bank0_rd_data_way0_f2[BV] & (btb_bank0_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & + btb_bank0_rd_data_way0_f2[BV] & (btb_bank0_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & ~({4{dec_tlu_way_wb_f==2'b0}} & branch_error_bank_conflict_f2[3:0]) & {4{ifc_fetch_req_f2_raw & ~leak_one_f2}}; - + assign tag_match_way1_f2[3:0] = {btb_bank3_rd_data_way1_f2[BV] & (btb_bank3_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank2_rd_data_way1_f2[BV] & (btb_bank2_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank1_rd_data_way1_f2[BV] & (btb_bank1_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), - btb_bank0_rd_data_way1_f2[BV] & (btb_bank0_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & + btb_bank0_rd_data_way1_f2[BV] & (btb_bank0_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & ~({4{dec_tlu_way_wb_f[0]}} & branch_error_bank_conflict_f2[3:0]) & {4{ifc_fetch_req_f2_raw & ~leak_one_f2}}; assign tag_match_way2_f2[3:0] = {btb_bank3_rd_data_way2_f2[BV] & (btb_bank3_rd_data_way2_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank2_rd_data_way2_f2[BV] & (btb_bank2_rd_data_way2_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank1_rd_data_way2_f2[BV] & (btb_bank1_rd_data_way2_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), - btb_bank0_rd_data_way2_f2[BV] & (btb_bank0_rd_data_way2_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & + btb_bank0_rd_data_way2_f2[BV] & (btb_bank0_rd_data_way2_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & ~({4{dec_tlu_way_wb_f[1]}} & branch_error_bank_conflict_f2[3:0]) & {4{ifc_fetch_req_f2_raw & ~leak_one_f2}}; -`else +`else // 2 -way SA, figure out the way hit and mux accordingly assign tag_match_way0_f2[3:0] = {btb_bank3_rd_data_way0_f2[BV] & (btb_bank3_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank2_rd_data_way0_f2[BV] & (btb_bank2_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank1_rd_data_way0_f2[BV] & (btb_bank1_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), - btb_bank0_rd_data_way0_f2[BV] & (btb_bank0_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & + btb_bank0_rd_data_way0_f2[BV] & (btb_bank0_rd_data_way0_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & ~({4{~dec_tlu_way_wb_f}} & branch_error_bank_conflict_f2[3:0]) & {4{ifc_fetch_req_f2_raw & ~leak_one_f2}}; - + assign tag_match_way1_f2[3:0] = {btb_bank3_rd_data_way1_f2[BV] & (btb_bank3_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank2_rd_data_way1_f2[BV] & (btb_bank2_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), btb_bank1_rd_data_way1_f2[BV] & (btb_bank1_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]), - btb_bank0_rd_data_way1_f2[BV] & (btb_bank0_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & + btb_bank0_rd_data_way1_f2[BV] & (btb_bank0_rd_data_way1_f2[`TAG] == fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0])} & ~({4{dec_tlu_way_wb_f}} & branch_error_bank_conflict_f2[3:0]) & {4{ifc_fetch_req_f2_raw & ~leak_one_f2}}; `endif - + // Both ways could hit, use the offset bit to reorder - + assign tag_match_way0_expanded_f2[7:0] = {tag_match_way0_f2[3] & (btb_bank3_rd_data_way0_f2[BOFF] ^ btb_bank3_rd_data_way0_f2[PC4]), tag_match_way0_f2[3] & ~(btb_bank3_rd_data_way0_f2[BOFF] ^ btb_bank3_rd_data_way0_f2[PC4]), tag_match_way0_f2[2] & (btb_bank2_rd_data_way0_f2[BOFF] ^ btb_bank2_rd_data_way0_f2[PC4]), @@ -578,7 +578,7 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] tag_match_way0_f2[1] & ~(btb_bank1_rd_data_way0_f2[BOFF] ^ btb_bank1_rd_data_way0_f2[PC4]), tag_match_way0_f2[0] & (btb_bank0_rd_data_way0_f2[BOFF] ^ btb_bank0_rd_data_way0_f2[PC4]), tag_match_way0_f2[0] & ~(btb_bank0_rd_data_way0_f2[BOFF] ^ btb_bank0_rd_data_way0_f2[PC4])}; - + assign tag_match_way1_expanded_f2[7:0] = {tag_match_way1_f2[3] & (btb_bank3_rd_data_way1_f2[BOFF] ^ btb_bank3_rd_data_way1_f2[PC4]), tag_match_way1_f2[3] & ~(btb_bank3_rd_data_way1_f2[BOFF] ^ btb_bank3_rd_data_way1_f2[PC4]), tag_match_way1_f2[2] & (btb_bank2_rd_data_way1_f2[BOFF] ^ btb_bank2_rd_data_way1_f2[PC4]), @@ -664,7 +664,7 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] assign mp_bank_decoded[3:0] = decode2_4(exu_mp_bank[1:0]); // create a onehot lru write vector assign mp_wrindex_dec[LRU_SIZE-1:0] = {{LRU_SIZE-1{1'b0}},1'b1} << exu_mp_addr[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; - + // fetch assign fetch_wrindex_dec[LRU_SIZE-1:0] = {{LRU_SIZE-1{1'b0}},1'b1} << btb_rd_addr_f2[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; @@ -691,17 +691,17 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] ((bht_valid_f2[2] & btb_sel_mask_f2[2]) | (bht_valid_f2[3] & btb_sel_mask_f2[3])) & ifc_fetch_req_f2 & ~leak_one_f2, ((bht_valid_f2[0] & btb_sel_mask_f2[0]) | (bht_valid_f2[1] & btb_sel_mask_f2[1])) & ifc_fetch_req_f2 & ~leak_one_f2}; - assign fetch_wrlru_b0[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & + assign fetch_wrlru_b0[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & {LRU_SIZE{lru_update_valid_f2[0]}}; - assign fetch_wrlru_b1[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & + assign fetch_wrlru_b1[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & {LRU_SIZE{lru_update_valid_f2[1]}}; - assign fetch_wrlru_b2[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & + assign fetch_wrlru_b2[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & {LRU_SIZE{lru_update_valid_f2[2]}}; - assign fetch_wrlru_b3[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & + assign fetch_wrlru_b3[LRU_SIZE-1:0] = fetch_wrindex_dec[LRU_SIZE-1:0] & {LRU_SIZE{lru_update_valid_f2[3]}}; `endif - + assign btb_lru_b0_hold[LRU_SIZE-1:0] = ~mp_wrlru_b0[LRU_SIZE-1:0] & ~fetch_wrlru_b0[LRU_SIZE-1:0]; assign btb_lru_b1_hold[LRU_SIZE-1:0] = ~mp_wrlru_b1[LRU_SIZE-1:0] & ~fetch_wrlru_b1[LRU_SIZE-1:0]; assign btb_lru_b2_hold[LRU_SIZE-1:0] = ~mp_wrlru_b2[LRU_SIZE-1:0] & ~fetch_wrlru_b2[LRU_SIZE-1:0]; @@ -724,7 +724,7 @@ assign btb_vmask_raw_f2[1] = (ifc_fetch_addr_f2[3] & ifc_fetch_addr_f2[2] fetch_replway_bank0_enc, fetch_replway_bank1_enc, fetch_replway_bank2_enc, fetch_replway_bank3_enc, fetch_replway_bank4_enc, fetch_replway_bank5_enc, fetch_replway_bank6_enc, fetch_replway_bank7_enc; logic [3:0][3:0] [2:0] lru_bank_rd_data_out; - + // // could have 2 ways hit for case where same bank, different offset hit. Update LRU accordingly logic [3:0] two_hits; assign two_hits[3:0] = (tag_match_way0_f2[3:0] & tag_match_way1_f2[3:0]) | @@ -738,7 +738,7 @@ logic [3:0] two_hits; assign fetch_lru_bank_hit_f2[3:0] = lru_update_valid_f2[3:0] & (tag_match_way0_f2[3:0] | tag_match_way1_f2[3:0] | tag_match_way2_f2[3:0]); // banks - for ( i=0; i<4; i++) begin : LRUBANKS + for ( i=0; i<4; i++) begin : LRUBANKS // only 4 indices here // encode the hit way in case the fetch hits assign hitway_enc[i] = tag_match_way1_f2[i] ? 2'b01 : tag_match_way2_f2[i] ? 2'b10 : 'b0; @@ -747,32 +747,32 @@ logic [3:0] two_hits; // index for (j=0 ; j<4 ; j++) begin : LRUFLOPS - + // mux the write data assign lru_bank_wr_data[i][j] = (exu_mp_valid & mp_bank_decoded[i]) ? mp_new_lru[2:0] : fetch_lru_bank_hit_f2[i] ? fetch_new_lru[i] : 'b0; - + // bank enable if there was a fetch hit or a mispredict // simul mp and fetch, mp has priority assign lru_bank_sel[i][j] = (~exu_mp_valid & fetch_lru_bank_hit_f2[i] & (btb_rd_addr_f2[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == j)) | ( exu_mp_valid & mp_bank_decoded[i] & (exu_mp_addr[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == j)); - - - rvdffs #(3) lru_bank (.*, + + + rvdffs #(3) lru_bank (.*, .clk (active_clk), .en (lru_bank_sel[i][j]), .din (lru_bank_wr_data[i][j]), .dout (lru_bank_rd_data_out[i][j])); - + end // block: LRUFLOPS end // block: LRUBANKS -always_comb begin : LRU_rd_mux - lru_bank0_rd_data_f2_in[2:0] = '0 ; - lru_bank1_rd_data_f2_in[2:0] = '0 ; - lru_bank2_rd_data_f2_in[2:0] = '0 ; +always_comb begin : LRU_rd_mux + lru_bank0_rd_data_f2_in[2:0] = '0 ; + lru_bank1_rd_data_f2_in[2:0] = '0 ; + lru_bank2_rd_data_f2_in[2:0] = '0 ; lru_bank3_rd_data_f2_in[2:0] = '0 ; for (int j=0; j<4; j++) begin - if (btb_rd_addr_f1[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == j) begin + if (btb_rd_addr_f1[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] == j) begin lru_bank0_rd_data_f2_in[2:0] = lru_bank_rd_data_out[0][j]; lru_bank1_rd_data_f2_in[2:0] = lru_bank_rd_data_out[1][j]; lru_bank2_rd_data_f2_in[2:0] = lru_bank_rd_data_out[2][j]; @@ -780,7 +780,7 @@ always_comb begin : LRU_rd_mux end end end // block: LRU_rd_mux - + rvdffe #(12) lru_dataoutf (.*, .en (ifc_fetch_req_f1), .din ({lru_bank0_rd_data_f2_in[2:0], @@ -836,19 +836,19 @@ end // block: LRU_rd_mux `else - + assign btb_lru_b0_ns[LRU_SIZE-1:0] = ( (btb_lru_b0_hold[LRU_SIZE-1:0] & btb_lru_b0_f[LRU_SIZE-1:0]) | (mp_wrlru_b0[LRU_SIZE-1:0] & {LRU_SIZE{~exu_mp_way}}) | (fetch_wrlru_b0[LRU_SIZE-1:0] & {LRU_SIZE{tag_match_way0_f2[0]}}) ); - + assign btb_lru_b1_ns[LRU_SIZE-1:0] = ( (btb_lru_b1_hold[LRU_SIZE-1:0] & btb_lru_b1_f[LRU_SIZE-1:0]) | (mp_wrlru_b1[LRU_SIZE-1:0] & {LRU_SIZE{~exu_mp_way}}) | (fetch_wrlru_b1[LRU_SIZE-1:0] & {LRU_SIZE{tag_match_way0_f2[1]}}) ); - + assign btb_lru_b2_ns[LRU_SIZE-1:0] = ( (btb_lru_b2_hold[LRU_SIZE-1:0] & btb_lru_b2_f[LRU_SIZE-1:0]) | (mp_wrlru_b2[LRU_SIZE-1:0] & {LRU_SIZE{~exu_mp_way}}) | (fetch_wrlru_b2[LRU_SIZE-1:0] & {LRU_SIZE{tag_match_way0_f2[2]}}) ); - + assign btb_lru_b3_ns[LRU_SIZE-1:0] = ( (btb_lru_b3_hold[LRU_SIZE-1:0] & btb_lru_b3_f[LRU_SIZE-1:0]) | (mp_wrlru_b3[LRU_SIZE-1:0] & {LRU_SIZE{~exu_mp_way}}) | (fetch_wrlru_b3[LRU_SIZE-1:0] & {LRU_SIZE{tag_match_way0_f2[3]}}) ); @@ -860,27 +860,27 @@ end // block: LRU_rd_mux assign way_raw[7:0] = tag_match_way1_expanded_f2[7:0] | (~wayhit_f2[7:0] & {{2{btb_lru_rd_f2[3]}}, {2{btb_lru_rd_f2[2]}}, {2{btb_lru_rd_f2[1]}}, {2{btb_lru_rd_f2[0]}}}); - rvdffe #(LRU_SIZE*4) btb_lru_ff (.*, .en(ifc_fetch_req_f2 | exu_mp_valid), + rvdffe #(LRU_SIZE*4) btb_lru_ff (.*, .en(ifc_fetch_req_f2 | exu_mp_valid), .din({btb_lru_b0_ns[(LRU_SIZE)-1:0], btb_lru_b1_ns[(LRU_SIZE)-1:0], btb_lru_b2_ns[(LRU_SIZE)-1:0], - btb_lru_b3_ns[(LRU_SIZE)-1:0]}), + btb_lru_b3_ns[(LRU_SIZE)-1:0]}), .dout({btb_lru_b0_f[(LRU_SIZE)-1:0], btb_lru_b1_f[(LRU_SIZE)-1:0], btb_lru_b2_f[(LRU_SIZE)-1:0], btb_lru_b3_f[(LRU_SIZE)-1:0]})); `endif // !`ifdef RV_BTB_48 - + // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- - + // mux out critical hit bank for pc computation // This is only useful for the first taken branch in the fetch group logic [16:1] btb_sel_data_f2; assign { - btb_rd_tgt_f2[11:0], - btb_rd_pc4_f2, + btb_rd_tgt_f2[11:0], + btb_rd_pc4_f2, btb_rd_boffset_f2, btb_rd_call_f2, btb_rd_ret_f2} = btb_sel_data_f2[16:1]; @@ -896,10 +896,10 @@ end // block: LRU_rd_mux logic [7:0] bp_valid_f2, bp_hist1_f2; - + // a valid taken target needs to kill the next fetch as we compute the target address assign ifu_bp_kill_next_f2 = |(bp_valid_f2[7:0] & bp_hist1_f2[7:0]) & ifc_fetch_req_f2 & ~leak_one_f2 & ~dec_tlu_bpred_disable; - + // Don't put calls/rets/ja in the predictor, force the bht taken instead assign bht_force_taken_f2[7:0] = {(btb_bank3o_rd_data_f2[CALL] | btb_bank3o_rd_data_f2[RET]), @@ -910,37 +910,37 @@ end // block: LRU_rd_mux (btb_bank1e_rd_data_f2[CALL] | btb_bank1e_rd_data_f2[RET]), (btb_bank0o_rd_data_f2[CALL] | btb_bank0o_rd_data_f2[RET]), (btb_bank0e_rd_data_f2[CALL] | btb_bank0e_rd_data_f2[RET])}; - + // taken and valid, otherwise, branch errors must clear the bht assign bht_valid_f2[7:0] = wayhit_f2[7:0]; - assign bht_dir_f2[7:0] = {(bht_force_taken_f2[7] | bht_bank7_rd_data_f2[1]) & bht_valid_f2[7], - (bht_force_taken_f2[6] | bht_bank6_rd_data_f2[1]) & bht_valid_f2[6], - (bht_force_taken_f2[5] | bht_bank5_rd_data_f2[1]) & bht_valid_f2[5], - (bht_force_taken_f2[4] | bht_bank4_rd_data_f2[1]) & bht_valid_f2[4], - (bht_force_taken_f2[3] | bht_bank3_rd_data_f2[1]) & bht_valid_f2[3], - (bht_force_taken_f2[2] | bht_bank2_rd_data_f2[1]) & bht_valid_f2[2], + assign bht_dir_f2[7:0] = {(bht_force_taken_f2[7] | bht_bank7_rd_data_f2[1]) & bht_valid_f2[7], + (bht_force_taken_f2[6] | bht_bank6_rd_data_f2[1]) & bht_valid_f2[6], + (bht_force_taken_f2[5] | bht_bank5_rd_data_f2[1]) & bht_valid_f2[5], + (bht_force_taken_f2[4] | bht_bank4_rd_data_f2[1]) & bht_valid_f2[4], + (bht_force_taken_f2[3] | bht_bank3_rd_data_f2[1]) & bht_valid_f2[3], + (bht_force_taken_f2[2] | bht_bank2_rd_data_f2[1]) & bht_valid_f2[2], (bht_force_taken_f2[1] | bht_bank1_rd_data_f2[1]) & bht_valid_f2[1], (bht_force_taken_f2[0] | bht_bank0_rd_data_f2[1]) & bht_valid_f2[0]}; - + // final inst_valid_mask. // vmask[7] is a 0, vmask[0] is a 1, initially // (assumes pc2 with boffset 0) // logic minus1, plus1; - + assign plus1 = ( (~btb_rd_pc4_f2 & btb_rd_boffset_f2 & ~ifc_fetch_addr_f2[1]) | ( btb_rd_pc4_f2 & ~btb_rd_boffset_f2 & ~ifc_fetch_addr_f2[1]) ); - + assign minus1 = ( (~btb_rd_pc4_f2 & ~btb_rd_boffset_f2 & ifc_fetch_addr_f2[1]) | ( btb_rd_pc4_f2 & btb_rd_boffset_f2 & ifc_fetch_addr_f2[1]) ); assign ifu_bp_inst_mask_f2[7:1] = ( ({7{ ifu_bp_kill_next_f2}} & btb_vmask_f2[7:1]) | ({7{~ifu_bp_kill_next_f2}} & 7'b1111111) ); - + logic [7:0] hist0_raw, hist1_raw, pc4_raw, pret_raw; - + // Branch prediction info is sent with the 2byte lane associated with the end of the branch. // Cases @@ -953,7 +953,7 @@ end // block: LRU_rd_mux // <------------> : PC4 branch, offset, indicate PC4, VALID, HIST on [0] // <------> : PC2 branch, offset, indicate VALID, HIST on [1] // <------> : PC2 branch, no offset, indicate VALID, HIST on [0] - // + // assign hist1_raw[7:0] = bht_force_taken_f2[7:0] | {bht_bank7_rd_data_f2[1], bht_bank6_rd_data_f2[1], @@ -963,7 +963,7 @@ end // block: LRU_rd_mux bht_bank2_rd_data_f2[1], bht_bank1_rd_data_f2[1], bht_bank0_rd_data_f2[1]}; - + assign hist0_raw[7:0] = {bht_bank7_rd_data_f2[0], bht_bank6_rd_data_f2[0], bht_bank5_rd_data_f2[0], @@ -972,28 +972,28 @@ end // block: LRU_rd_mux bht_bank2_rd_data_f2[0], bht_bank1_rd_data_f2[0], bht_bank0_rd_data_f2[0]}; - - - assign pc4_raw[7:0] = {wayhit_f2[7] & btb_bank3o_rd_data_f2[PC4], + + + assign pc4_raw[7:0] = {wayhit_f2[7] & btb_bank3o_rd_data_f2[PC4], wayhit_f2[6] & btb_bank3e_rd_data_f2[PC4], - wayhit_f2[5] & btb_bank2o_rd_data_f2[PC4], - wayhit_f2[4] & btb_bank2e_rd_data_f2[PC4], - wayhit_f2[3] & btb_bank1o_rd_data_f2[PC4], - wayhit_f2[2] & btb_bank1e_rd_data_f2[PC4], - wayhit_f2[1] & btb_bank0o_rd_data_f2[PC4], + wayhit_f2[5] & btb_bank2o_rd_data_f2[PC4], + wayhit_f2[4] & btb_bank2e_rd_data_f2[PC4], + wayhit_f2[3] & btb_bank1o_rd_data_f2[PC4], + wayhit_f2[2] & btb_bank1e_rd_data_f2[PC4], + wayhit_f2[1] & btb_bank0o_rd_data_f2[PC4], wayhit_f2[0] & btb_bank0e_rd_data_f2[PC4]}; - assign pret_raw[7:0] = {wayhit_f2[3] & ~btb_bank3o_rd_data_f2[CALL] & btb_bank3o_rd_data_f2[RET], + assign pret_raw[7:0] = {wayhit_f2[3] & ~btb_bank3o_rd_data_f2[CALL] & btb_bank3o_rd_data_f2[RET], wayhit_f2[3] & ~btb_bank3e_rd_data_f2[CALL] & btb_bank3e_rd_data_f2[RET], - wayhit_f2[2] & ~btb_bank2o_rd_data_f2[CALL] & btb_bank2o_rd_data_f2[RET], - wayhit_f2[2] & ~btb_bank2e_rd_data_f2[CALL] & btb_bank2e_rd_data_f2[RET], - wayhit_f2[1] & ~btb_bank1o_rd_data_f2[CALL] & btb_bank1o_rd_data_f2[RET], - wayhit_f2[1] & ~btb_bank1e_rd_data_f2[CALL] & btb_bank1e_rd_data_f2[RET], - wayhit_f2[0] & ~btb_bank0o_rd_data_f2[CALL] & btb_bank0o_rd_data_f2[RET], + wayhit_f2[2] & ~btb_bank2o_rd_data_f2[CALL] & btb_bank2o_rd_data_f2[RET], + wayhit_f2[2] & ~btb_bank2e_rd_data_f2[CALL] & btb_bank2e_rd_data_f2[RET], + wayhit_f2[1] & ~btb_bank1o_rd_data_f2[CALL] & btb_bank1o_rd_data_f2[RET], + wayhit_f2[1] & ~btb_bank1e_rd_data_f2[CALL] & btb_bank1e_rd_data_f2[RET], + wayhit_f2[0] & ~btb_bank0o_rd_data_f2[CALL] & btb_bank0o_rd_data_f2[RET], wayhit_f2[0] & ~btb_bank0e_rd_data_f2[CALL] & btb_bank0e_rd_data_f2[RET]}; - + // GHR - + // Figure out how many valid branches are in the fetch group assign fgmask_f2[6] = (~ifc_fetch_addr_f2[1]) | (~ifc_fetch_addr_f2[2]) | ( ~ifc_fetch_addr_f2[3]); @@ -1007,13 +1007,13 @@ assign fgmask_f2[1] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2]); assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] & ~ifc_fetch_addr_f2[1]); - assign btb_sel_mask_f2[7:0] = {btb_sel_f2[7], - |btb_sel_f2[7:6] & fgmask_f2[6], - |btb_sel_f2[7:5] & fgmask_f2[5], - |btb_sel_f2[7:4] & fgmask_f2[4], - |btb_sel_f2[7:3] & fgmask_f2[3], - |btb_sel_f2[7:2] & fgmask_f2[2], - |btb_sel_f2[7:1] & fgmask_f2[1], + assign btb_sel_mask_f2[7:0] = {btb_sel_f2[7], + |btb_sel_f2[7:6] & fgmask_f2[6], + |btb_sel_f2[7:5] & fgmask_f2[5], + |btb_sel_f2[7:4] & fgmask_f2[4], + |btb_sel_f2[7:3] & fgmask_f2[3], + |btb_sel_f2[7:2] & fgmask_f2[2], + |btb_sel_f2[7:1] & fgmask_f2[1], |btb_sel_f2[7:0] & fgmask_f2[0]}; // count the valids with masking based on first taken @@ -1021,18 +1021,18 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] // Note that the following property holds // P: prior ghr, H: history bit of last valid branch in line (could be 1 or 0) - // Num valid branches What new GHR must be + // Num valid branches What new GHR must be // >=4 000H // 3 P00H // 2 PP0H // 1 PPPH // 0 PPPP - + assign final_h = |(btb_sel_f2[7:0] & bht_dir_f2[7:0]); - + assign merged_ghr[`RV_BHT_GHR_RANGE] = ( ({`RV_BHT_GHR_SIZE{num_valids[3:0] >= 4'h4}} & {`RV_BHT_GHR_PAD, final_h }) | // 000H ({`RV_BHT_GHR_SIZE{num_valids[3:0] == 4'h3}} & {`RV_BHT_GHR_PAD2, final_h}) | // P00H -`ifdef RV_BHT_GHR_SIZE_2 +`ifdef RV_BHT_GHR_SIZE_2 ({`RV_BHT_GHR_SIZE{num_valids[3:0] == 4'h2}} & { 1'b0, final_h}) | // PP0H `else ({`RV_BHT_GHR_SIZE{num_valids[3:0] == 4'h2}} & {fghr[`RV_BHT_GHR_SIZE-3:0], 1'b0, final_h}) | // PP0H @@ -1042,14 +1042,14 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] logic [`RV_BHT_GHR_RANGE] exu_flush_ghr; assign exu_flush_ghr[`RV_BHT_GHR_RANGE] = exu_mp_fghr[`RV_BHT_GHR_RANGE]; - + assign fghr_ns[`RV_BHT_GHR_RANGE] = ( ({`RV_BHT_GHR_SIZE{exu_flush_final}} & exu_flush_ghr[`RV_BHT_GHR_RANGE]) | ({`RV_BHT_GHR_SIZE{~exu_flush_final & ifc_fetch_req_f2_raw & ~leak_one_f2}} & merged_ghr[`RV_BHT_GHR_RANGE]) | ({`RV_BHT_GHR_SIZE{~exu_flush_final & ~(ifc_fetch_req_f2_raw & ~leak_one_f2)}} & fghr[`RV_BHT_GHR_RANGE])); rvdff #(`RV_BHT_GHR_SIZE) fetchghr (.*, .clk(active_clk), .din(fghr_ns[`RV_BHT_GHR_RANGE]), .dout(fghr[`RV_BHT_GHR_RANGE])); assign ifu_bp_fghr_f2[`RV_BHT_GHR_RANGE] = fghr[`RV_BHT_GHR_RANGE]; - + `ifdef RV_BTB_48 assign ifu_bp_way_f2 = {fetch_replway_bank7_enc[1:0], @@ -1074,44 +1074,44 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] // Truncate taken and valid, used for detecting a taken branch in the fetch group always_comb begin casez(ifc_fetch_addr_f2[3:1]) - 3'b000 : begin + 3'b000 : begin bp_hist1_f2[7:0] = hist1_raw[7:0]; bp_valid_f2[7:0] = wayhit_f2[7:0]; end - 3'b001 : begin + 3'b001 : begin bp_hist1_f2[7:0] = {1'b0, hist1_raw[7:1]}; bp_valid_f2[7:0] = {1'b0, wayhit_f2[7:1]}; end - 3'b010 : begin + 3'b010 : begin bp_hist1_f2[7:0] = {2'b0, hist1_raw[7:2]}; bp_valid_f2[7:0] = {2'b0, wayhit_f2[7:2]}; end - 3'b011 : begin + 3'b011 : begin bp_hist1_f2[7:0] = {3'b0, hist1_raw[7:3]}; bp_valid_f2[7:0] = {3'b0, wayhit_f2[7:3]}; end - 3'b100 : begin + 3'b100 : begin bp_hist1_f2[7:0] = {4'b0, hist1_raw[7:4]}; bp_valid_f2[7:0] = {4'b0, wayhit_f2[7:4]}; end - 3'b101 : begin + 3'b101 : begin bp_hist1_f2[7:0] = {5'b0, hist1_raw[7:5]}; bp_valid_f2[7:0] = {5'b0, wayhit_f2[7:5]}; end - 3'b110 : begin + 3'b110 : begin bp_hist1_f2[7:0] = {6'b0, hist1_raw[7:6]}; bp_valid_f2[7:0] = {6'b0, wayhit_f2[7:6]}; end - 3'b111 : begin + 3'b111 : begin bp_hist1_f2[7:0] = {7'b0, hist1_raw[7]}; bp_valid_f2[7:0] = {7'b0, wayhit_f2[7]}; end default: begin bp_hist1_f2[7:0] = hist1_raw[7:0]; - bp_valid_f2[7:0] = wayhit_f2[7:0]; - end + bp_valid_f2[7:0] = wayhit_f2[7:0]; + end endcase // casex (ifc_fetch_addr_f1[3:2]) - + end // compute target // Form the fetch group offset based on the btb hit location and the location of the branch within the 4 byte chunk @@ -1120,12 +1120,12 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] wire [2:0] btb_sel_f2_enc, btb_sel_f2_enc_shift; assign btb_sel_f2_enc[2:0] = encode8_3(btb_sel_f2[7:0]); assign btb_sel_f2_enc_shift[2:0] = encode8_3({1'b0,btb_sel_f2[7:1]}); - + assign bp_total_branch_offset_f2[3:1] = (({3{ btb_rd_pc4_f2}} & btb_sel_f2_enc_shift[2:0]) | ({3{~btb_rd_pc4_f2}} & btb_sel_f2_enc[2:0]) | ({3{btb_fg_crossing_f2}})); - + logic [31:4] adder_pc_in_f2, ifc_fetch_adder_prior; rvdffe #(28) faddrf2_ff (.*, .en(ifc_fetch_req_f2 & ~ifu_bp_kill_next_f2 & ic_hit_f2), .din(ifc_fetch_addr_f2[31:4]), .dout(ifc_fetch_adder_prior[31:4])); @@ -1133,24 +1133,24 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] assign adder_pc_in_f2[31:4] = ( ({28{ btb_fg_crossing_f2}} & ifc_fetch_adder_prior[31:4]) | ({28{~btb_fg_crossing_f2}} & ifc_fetch_addr_f2[31:4])); - + rvbradder predtgt_addr (.pc({adder_pc_in_f2[31:4], bp_total_branch_offset_f2[3:1]}), .offset(btb_rd_tgt_f2[11:0]), - .dout(bp_btb_target_adder_f2[31:1]) + .dout(bp_btb_target_adder_f2[31:1]) ); // mux in the return stack address here for a predicted return assign ifu_bp_btb_target_f2[31:1] = btb_rd_ret_f2 & ~btb_rd_call_f2 ? rets_out[0][31:1] : bp_btb_target_adder_f2[31:1]; // ---------------------------------------------------------------------- - // Return Stack + // Return Stack // ---------------------------------------------------------------------- rvbradder rs_addr (.pc({adder_pc_in_f2[31:4], bp_total_branch_offset_f2[3:1]}), .offset({10'b0, btb_rd_pc4_f2, ~btb_rd_pc4_f2}), - .dout(bp_rs_call_target_f2[31:1]) + .dout(bp_rs_call_target_f2[31:1]) ); - + // Calls/Rets are always taken, so there shouldn't be a push and pop in the same fetch group logic rs_overpop_correct, rsoverpop_valid_ns, rsoverpop_valid_f; logic [31:1] rsoverpop_ns, rsoverpop_f; @@ -1178,60 +1178,60 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] assign e4_rs_correct = 1'b0; assign rs_correct = 1'b0; `endif - + assign rs_push = ((btb_rd_call_f2 & ~btb_rd_ret_f2 & ifu_bp_kill_next_f2) | (rs_overpop_correct & ~rs_underpop_correct)) & ~rs_correct & ~e4_rs_correct; assign rs_pop = ((btb_rd_ret_f2 & ~btb_rd_call_f2 & ifu_bp_kill_next_f2) | (rs_underpop_correct & ~rs_overpop_correct)) & ~rs_correct & ~e4_rs_correct; assign rs_hold = ~rs_push & ~rs_pop & ~rs_overpop_correct & ~rs_underpop_correct & ~rs_correct & ~e4_rs_correct; - - // Fetch based + + // Fetch based assign rets_in[0][31:1] = ( ({31{rs_overpop_correct & rs_underpop_correct}} & rsoverpop_f[31:1]) | ({31{rs_push & rs_overpop_correct}} & rsoverpop_f[31:1]) | ({31{rs_push & ~rs_overpop_correct}} & bp_rs_call_target_f2[31:1]) | -`ifdef REAL_COMM_RS +`ifdef REAL_COMM_RS ({31{rs_correct}} & e1_rets_out[0][31:1]) | ({31{e4_rs_correct}} & e4_rets_out[0][31:1]) | -`endif +`endif ({31{rs_pop}} & rets_out[1][31:1]) ); assign rsenable[0] = ~rs_hold; - + for (i=0; i<`RV_RET_STACK_SIZE; i++) begin : retstack // for the last entry in the stack, we don't have a pop position - if(i==`RV_RET_STACK_SIZE-1) begin -`ifdef REAL_COMM_RS + if(i==`RV_RET_STACK_SIZE-1) begin +`ifdef REAL_COMM_RS assign rets_in[i][31:1] = ( ({31{rs_push}} & rets_out[i-1][31:1]) | ({31{rs_correct}} & e1_rets_out[i][31:1]) | ({31{e4_rs_correct}} & e4_rets_out[i][31:1]) ); `else assign rets_in[i][31:1] = rets_out[i-1][31:1]; -`endif +`endif assign rsenable[i] = rs_push | rs_correct | e4_rs_correct; end else if(i>0) begin -`ifdef REAL_COMM_RS +`ifdef REAL_COMM_RS assign rets_in[i][31:1] = ( ({31{rs_push}} & rets_out[i-1][31:1]) | ({31{rs_pop}} & rets_out[i+1][31:1]) | ({31{rs_correct}} & e1_rets_out[i][31:1]) | ({31{e4_rs_correct}} & e4_rets_out[i][31:1]) ); -`else +`else assign rets_in[i][31:1] = ( ({31{rs_push}} & rets_out[i-1][31:1]) | ({31{rs_pop}} & rets_out[i+1][31:1]) ); -`endif +`endif assign rsenable[i] = rs_push | rs_pop | rs_correct | e4_rs_correct; - end + end rvdffe #(31) rets_ff (.*, .en(rsenable[i]), .din(rets_in[i][31:1]), .dout(rets_out[i][31:1])); end : retstack - + `ifdef REAL_COMM_RS logic [31:1] e1_rs_call0_target_f2, e1_rs_call1_target_f2, e1_rs_call_target_f2, e4_rs_call0_target_f2, e4_rs_call1_target_f2, e4_rs_call_target_f2; logic e1_null, e1_rs_push1, e1_rs_push2, e1_rs_pop1, e1_rs_pop2, e1_rs_hold; logic e4_null, e4_rs_push1, e4_rs_push2, e4_rs_pop1, e4_rs_pop2, e4_rs_hold; - // E1 based + // E1 based assign e4_rs_correct = dec_tlu_flush_lower_wb; assign e1_null = exu_rets_e1_pkt.pc0_call & exu_rets_e1_pkt.pc1_ret; assign e1_rs_push1 = (exu_rets_e1_pkt.pc0_call ^ exu_rets_e1_pkt.pc1_call) & ~e1_null & ~e4_rs_correct; @@ -1242,15 +1242,15 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] rvbradder e1_rs_addr0 (.pc({exu_i0_pc_e1[31:1]}), .offset({10'b0, exu_rets_e1_pkt.pc0_pc4, ~exu_rets_e1_pkt.pc0_pc4}), - .dout(e1_rs_call0_target_f2[31:1]) + .dout(e1_rs_call0_target_f2[31:1]) ); rvbradder e1_rs_addr1 (.pc({exu_i1_pc_e1[31:1]}), .offset({10'b0, exu_rets_e1_pkt.pc1_pc4, ~exu_rets_e1_pkt.pc1_pc4}), - .dout(e1_rs_call1_target_f2[31:1]) + .dout(e1_rs_call1_target_f2[31:1]) ); assign e1_rs_call_target_f2[31:1] = exu_rets_e1_pkt.pc0_call ? e1_rs_call0_target_f2[31:1] : e1_rs_call1_target_f2[31:1]; - + assign e1_rets_in[0][31:1] = ( ({31{e1_rs_push1}} & e1_rs_call_target_f2[31:1]) | ({31{e1_rs_push2}} & e1_rs_call1_target_f2[31:1]) | ({31{e1_rs_pop1}} & e1_rets_out[1][31:1]) | @@ -1269,7 +1269,7 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] for (i=0; i<`RV_RET_STACK_SIZE; i++) begin : e1_retstack // for the last entry in the stack, we don't have a pop position - if(i==`RV_RET_STACK_SIZE-1) + if(i==`RV_RET_STACK_SIZE-1) assign e1_rets_in[i][31:1] = ( ({31{e1_rs_push1}} & e1_rets_out[i-1][31:1]) | ({31{e1_rs_push2}} & e1_rets_out[i-2][31:1]) | ({31{e4_rs_correct}} & e4_rets_out[i][31:1]) | @@ -1280,7 +1280,7 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] ({31{e1_rs_pop1}} & e1_rets_out[i+1][31:1]) | ({31{e4_rs_correct}} & e4_rets_out[i][31:1]) | ({31{e1_rs_hold}} & e1_rets_out[i][31:1]) ); - + else if(i>1) assign e1_rets_in[i][31:1] = ( ({31{e1_rs_push1}} & e1_rets_out[i-1][31:1]) | ({31{e1_rs_push2}} & e1_rets_out[i-2][31:1]) | @@ -1289,12 +1289,12 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] ({31{e4_rs_correct}} & e4_rets_out[i][31:1]) | ({31{e1_rs_hold}} & e1_rets_out[i][31:1]) ); - + rvdff #(31) e1_rets_ff (.*, .din(e1_rets_in[i][31:1]), .dout(e1_rets_out[i][31:1])); end : e1_retstack - // E4 based + // E4 based assign e4_null = exu_rets_e4_pkt.pc0_call & exu_rets_e4_pkt.pc1_ret; assign e4_rs_push1 = (exu_rets_e4_pkt.pc0_call ^ exu_rets_e4_pkt.pc1_call) & ~e4_null; assign e4_rs_push2 = (exu_rets_e4_pkt.pc0_call & exu_rets_e4_pkt.pc1_call); @@ -1304,15 +1304,15 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] rvbradder e4_rs_addr0 (.pc({dec_tlu_i0_pc_e4[31:1]}), .offset({10'b0, exu_rets_e4_pkt.pc0_pc4, ~exu_rets_e4_pkt.pc0_pc4}), - .dout(e4_rs_call0_target_f2[31:1]) + .dout(e4_rs_call0_target_f2[31:1]) ); rvbradder e4_rs_addr1 (.pc({dec_tlu_i1_pc_e4[31:1]}), .offset({10'b0, exu_rets_e4_pkt.pc1_pc4, ~exu_rets_e4_pkt.pc1_pc4}), - .dout(e4_rs_call1_target_f2[31:1]) + .dout(e4_rs_call1_target_f2[31:1]) ); assign e4_rs_call_target_f2[31:1] = exu_rets_e4_pkt.pc0_call ? e4_rs_call0_target_f2[31:1] : e4_rs_call1_target_f2[31:1]; - + assign e4_rets_in[0][31:1] = ( ({31{e4_rs_push1}} & e4_rs_call_target_f2[31:1]) | ({31{e4_rs_push2}} & e4_rs_call1_target_f2[31:1]) | ({31{e4_rs_pop1}} & e4_rets_out[1][31:1]) | @@ -1329,7 +1329,7 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] for (i=0; i<`RV_RET_STACK_SIZE; i++) begin : e4_retstack // for the last entry in the stack, we don't have a pop position - if(i==`RV_RET_STACK_SIZE-1) + if(i==`RV_RET_STACK_SIZE-1) assign e4_rets_in[i][31:1] = ( ({31{e4_rs_push1}} & e4_rets_out[i-1][31:1]) | ({31{e4_rs_push2}} & e4_rets_out[i-2][31:1]) | ({31{e4_rs_hold}} & e4_rets_out[i][31:1]) ); @@ -1338,7 +1338,7 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] ({31{e4_rs_push2}} & e4_rets_out[i-2][31:1]) | ({31{e4_rs_pop1}} & e4_rets_out[i+1][31:1]) | ({31{e4_rs_hold}} & e4_rets_out[i][31:1]) ); - + else if(i>1) assign e4_rets_in[i][31:1] = ( ({31{e4_rs_push1}} & e4_rets_out[i-1][31:1]) | ({31{e4_rs_push2}} & e4_rets_out[i-2][31:1]) | @@ -1346,47 +1346,47 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] ({31{e4_rs_pop2}} & e4_rets_out[i+2][31:1]) | ({31{e4_rs_hold}} & e4_rets_out[i][31:1]) ); - + rvdff #(31) e4_rets_ff (.*, .din(e4_rets_in[i][31:1]), .dout(e4_rets_out[i][31:1])); end : e4_retstack `endif // `ifdef REAL_COMM_RS - + // ---------------------------------------------------------------------- // WRITE // ---------------------------------------------------------------------- - + assign dec_tlu_error_wb = dec_tlu_br0_start_error_wb | dec_tlu_br0_error_wb | dec_tlu_br1_start_error_wb | dec_tlu_br1_error_wb; assign dec_tlu_all_banks_error_wb = dec_tlu_br0_start_error_wb | (~dec_tlu_br0_error_wb & dec_tlu_br1_start_error_wb); assign dec_tlu_error_bank_wb[1:0] = (dec_tlu_br0_error_wb | dec_tlu_br0_start_error_wb) ? dec_tlu_br0_bank_wb[1:0] : dec_tlu_br1_bank_wb[1:0]; assign btb_error_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = (dec_tlu_br0_error_wb | dec_tlu_br0_start_error_wb) ? dec_tlu_br0_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] : dec_tlu_br1_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; - assign dec_tlu_way_wb = (dec_tlu_br0_error_wb | dec_tlu_br0_start_error_wb) ? dec_tlu_br0_way_wb : dec_tlu_br1_way_wb; + assign dec_tlu_way_wb = (dec_tlu_br0_error_wb | dec_tlu_br0_start_error_wb) ? dec_tlu_br0_way_wb : dec_tlu_br1_way_wb; assign btb_valid = exu_mp_valid & ~dec_tlu_error_wb; assign btb_wr_tag[`RV_BTB_BTAG_SIZE-1:0] = exu_mp_btag[`RV_BTB_BTAG_SIZE-1:0]; rvbtb_tag_hash rdtagf1(.hash(fetch_rd_tag_f1[`RV_BTB_BTAG_SIZE-1:0]), .pc({ifc_fetch_addr_f1[31:4], 3'b0})); rvdff #(`RV_BTB_BTAG_SIZE) rdtagf (.*, .clk(active_clk), .din({fetch_rd_tag_f1[`RV_BTB_BTAG_SIZE-1:0]}), .dout({fetch_rd_tag_f2[`RV_BTB_BTAG_SIZE-1:0]})); - + assign btb_wr_data[16+`RV_BTB_BTAG_SIZE:0] = {btb_wr_tag[`RV_BTB_BTAG_SIZE-1:0], exu_mp_tgt[11: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; -`ifdef RV_BTB_48 +`ifdef RV_BTB_48 assign btb_wr_en_way0[3:0] = ( ({4{(exu_mp_way==2'b0) & exu_mp_valid_write & ~dec_tlu_error_wb}} & decode2_4(exu_mp_bank[1:0])) | ({4{(dec_tlu_way_wb==2'b0) & dec_tlu_error_wb & ~dec_tlu_all_banks_error_wb}} & decode2_4(dec_tlu_error_bank_wb[1:0])) | ({4{(dec_tlu_way_wb==2'b0) & dec_tlu_all_banks_error_wb}})); - + assign btb_wr_en_way1[3:0] = ( ({4{exu_mp_way[0] & exu_mp_valid_write & ~dec_tlu_error_wb}} & decode2_4(exu_mp_bank[1:0])) | ({4{dec_tlu_way_wb[0] & dec_tlu_error_wb & ~dec_tlu_all_banks_error_wb}} & decode2_4(dec_tlu_error_bank_wb[1:0])) | ({4{dec_tlu_way_wb[0] & dec_tlu_all_banks_error_wb}})); - + assign btb_wr_en_way2[3:0] = ( ({4{exu_mp_way[1] & exu_mp_valid_write & ~dec_tlu_error_wb}} & decode2_4(exu_mp_bank[1:0])) | ({4{dec_tlu_way_wb[1] & dec_tlu_error_wb & ~dec_tlu_all_banks_error_wb}} & decode2_4(dec_tlu_error_bank_wb[1:0])) | ({4{dec_tlu_way_wb[1] & dec_tlu_all_banks_error_wb}})); @@ -1394,14 +1394,14 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] assign btb_wr_en_way0[3:0] = ( ({4{~exu_mp_way & exu_mp_valid_write & ~dec_tlu_error_wb}} & decode2_4(exu_mp_bank[1:0])) | ({4{~dec_tlu_way_wb & dec_tlu_error_wb & ~dec_tlu_all_banks_error_wb}} & decode2_4(dec_tlu_error_bank_wb[1:0])) | ({4{~dec_tlu_way_wb & dec_tlu_all_banks_error_wb}})); - + assign btb_wr_en_way1[3:0] = ( ({4{exu_mp_way & exu_mp_valid_write & ~dec_tlu_error_wb}} & decode2_4(exu_mp_bank[1:0])) | ({4{dec_tlu_way_wb & dec_tlu_error_wb & ~dec_tlu_all_banks_error_wb}} & decode2_4(dec_tlu_error_bank_wb[1:0])) | ({4{dec_tlu_way_wb & dec_tlu_all_banks_error_wb}})); - - + + `endif - + assign btb_wr_addr[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = dec_tlu_error_wb ? btb_error_addr_wb[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] : exu_mp_addr[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO]; logic [1:0] bht_wr_data0, bht_wr_data1, bht_wr_data2; @@ -1412,10 +1412,10 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] assign bht_wr_en1[7:0] = {8{dec_tlu_br1_v_wb}} & decode3_8({dec_tlu_br1_bank_wb[1:0], dec_tlu_br1_middle_wb}); assign bht_wr_en2[7:0] = {8{dec_tlu_br0_v_wb}} & decode3_8({dec_tlu_br0_bank_wb[1:0], dec_tlu_br0_middle_wb}); - // Experiments show this is the best priority scheme for same bank/index writes at the same time. - assign bht_wr_data0[1:0] = exu_mp_hist[1:0]; // lowest priority + // Experiments show this is the best priority scheme for same bank/index writes at the same time. + assign bht_wr_data0[1:0] = exu_mp_hist[1:0]; // lowest priority assign bht_wr_data1[1:0] = dec_tlu_br1_hist_wb[1:0]; - assign bht_wr_data2[1:0] = dec_tlu_br0_hist_wb[1:0]; // highest priority + assign bht_wr_data2[1:0] = dec_tlu_br0_hist_wb[1:0]; // highest priority @@ -1432,74 +1432,74 @@ assign fgmask_f2[0] = (~ifc_fetch_addr_f2[3] & ~ifc_fetch_addr_f2[2] assign bht_wr_addr2[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO] = br0_hashed_wb[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO]; assign bht_rd_addr_f1[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO] = bht_rd_addr_hashed_f1[`RV_BHT_ADDR_HI:`RV_BHT_ADDR_LO]; - + // ---------------------------------------------------------------------- - // Structures. Using FLOPS + // Structures. Using FLOPS // ---------------------------------------------------------------------- // BTB // Entry -> tag[`RV_BTB_BTAG_SIZE-1:0], toffset[11:0], pc4, boffset, call, ret, valid - - + + for (j=0 ; j direction, strength - // + // //----------------------------------------------------------------------------- logic [7:0] [(`RV_BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0][NUM_BHT_LOOP-1:0][1:0] bht_bank_wr_data ; logic [7:0] [`RV_BHT_ARRAY_DEPTH-1:0] [1:0] bht_bank_rd_data_out ; - logic [1:0] bht_bank0_rd_data_f2_in, bht_bank1_rd_data_f2_in, bht_bank2_rd_data_f2_in, bht_bank3_rd_data_f2_in; - logic [1:0] bht_bank4_rd_data_f2_in, bht_bank5_rd_data_f2_in, bht_bank6_rd_data_f2_in, bht_bank7_rd_data_f2_in; + logic [1:0] bht_bank0_rd_data_f2_in, bht_bank1_rd_data_f2_in, bht_bank2_rd_data_f2_in, bht_bank3_rd_data_f2_in; + logic [1:0] bht_bank4_rd_data_f2_in, bht_bank5_rd_data_f2_in, bht_bank6_rd_data_f2_in, bht_bank7_rd_data_f2_in; logic [7:0] [(`RV_BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0] bht_bank_clken ; logic [7:0] [(`RV_BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0] bht_bank_clk ; logic [7:0] [(`RV_BHT_ARRAY_DEPTH/NUM_BHT_LOOP)-1:0][NUM_BHT_LOOP-1:0] bht_bank_sel ; - for ( i=0; i<8; i++) begin : BANKS + for ( i=0; i<8; i++) begin : BANKS for (genvar k=0 ; k < (`RV_BHT_ARRAY_DEPTH)/NUM_BHT_LOOP ; k++) begin : BHT_CLK_GROUP - assign bht_bank_clken[i][k] = (bht_wr_en0[i] & ((bht_wr_addr0[`RV_BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)) | - (bht_wr_en1[i] & ((bht_wr_addr1[`RV_BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)) | - (bht_wr_en2[i] & ((bht_wr_addr2[`RV_BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)); + assign bht_bank_clken[i][k] = (bht_wr_en0[i] & ((bht_wr_addr0[`RV_BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)) | + (bht_wr_en1[i] & ((bht_wr_addr1[`RV_BHT_ADDR_HI: NUM_BHT_LOOP_OUTER_LO]==k) | BHT_NO_ADDR_MATCH)) | + (bht_wr_en2[i] & ((bht_wr_addr2[`RV_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]), .* ); - + for (j=0 ; j (~$past(ahb_hready) & $past(ahb_hresp)); @@ -272,5 +272,5 @@ module ahb_to_axi4 #(parameter TAG = 1) ( $display("Bus Error with hReady isn't preceded with Bus Error without hready"); `endif - + endmodule // ahb_to_axi4 \ No newline at end of file diff --git a/design/lib/axi4_to_ahb.sv b/design/lib/axi4_to_ahb.sv index 7c309b4..b0641dc 100644 --- a/design/lib/axi4_to_ahb.sv +++ b/design/lib/axi4_to_ahb.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,8 +16,8 @@ //******************************************************************************** // $Id$ // -// Owner: -// Function: AXI4 -> AHB Bridge +// Owner: +// Function: AXI4 -> AHB Bridge // Comments: // //******************************************************************************** @@ -25,11 +25,11 @@ module axi4_to_ahb #(parameter TAG = 1) ( input clk, input rst_l, - input scan_mode, - input bus_clk_en, + input scan_mode, + input bus_clk_en, input clk_override, - - // AXI signals + + // AXI signals // AXI Write Channels input logic axi_awvalid, output logic axi_awready, @@ -38,7 +38,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( input logic [2:0] axi_awsize, input logic [2:0] axi_awprot, - input logic axi_wvalid, + input logic axi_wvalid, output logic axi_wready, input logic [63:0] axi_wdata, input logic [7:0] axi_wstrb, @@ -53,7 +53,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( input logic axi_arvalid, output logic axi_arready, input logic [TAG-1:0] axi_arid, - input logic [31:0] axi_araddr, + input logic [31:0] axi_araddr, input logic [2:0] axi_arsize, input logic [2:0] axi_arprot, @@ -62,9 +62,9 @@ module axi4_to_ahb #(parameter TAG = 1) ( output logic [TAG-1:0] axi_rid, output logic [63:0] axi_rdata, output logic [1:0] axi_rresp, - output logic axi_rlast, + output logic axi_rlast, - // AHB-Lite signals + // AHB-Lite signals output logic [31:0] ahb_haddr, // ahb bus address output logic [2:0] ahb_hburst, // tied to 0 output logic ahb_hmastlock, // tied to 0 @@ -74,7 +74,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( output logic ahb_hwrite, // ahb bus write output logic [63:0] ahb_hwdata, // ahb bus write data - input logic [63:0] ahb_hrdata, // ahb bus read data + input logic [63:0] ahb_hrdata, // ahb bus read data input logic ahb_hready, // slave ready to accept transaction input logic ahb_hresp // slave response (high indicates erro) @@ -100,25 +100,25 @@ module axi4_to_ahb #(parameter TAG = 1) ( logic [31:0] wrbuf_addr; logic [63:0] wrbuf_data; logic [7:0] wrbuf_byteen; - + logic bus_write_clk_en; logic bus_clk, bus_write_clk; - + logic master_valid; logic master_ready; logic [TAG-1:0] master_tag; - logic [31:0] master_addr; + logic [31:0] master_addr; logic [63:0] master_wdata; logic [2:0] master_size; logic [2:0] master_opc; - + // Buffer signals (one entry buffer) logic [31:0] buf_addr; logic [1:0] buf_size; logic buf_write; logic [7:0] buf_byteen; logic buf_aligned; - logic [63:0] buf_data; + logic [63:0] buf_data; logic [TAG-1:0] buf_tag; //Miscellaneous signals @@ -130,19 +130,19 @@ module axi4_to_ahb #(parameter TAG = 1) ( logic buf_write_in; logic buf_aligned_in; logic [2:0] buf_size_in; - + logic buf_state_en; logic buf_wr_en; logic buf_data_wr_en; logic slvbuf_error_en; logic wr_cmd_vld; - + logic cmd_done_rst, cmd_done, cmd_doneQ; logic trxn_done; logic [2:0] buf_cmd_byte_ptr, buf_cmd_byte_ptrQ, buf_cmd_nxtbyte_ptr; logic buf_cmd_byte_ptr_en; logic found; - + logic slave_valid_pre; logic ahb_hready_q; logic ahb_hresp_q; @@ -157,9 +157,9 @@ module axi4_to_ahb #(parameter TAG = 1) ( logic slvbuf_error_in; logic slvbuf_wr_en; - logic bypass_en; + logic bypass_en; logic rd_bypass_idle; - + logic last_addr_en; logic [31:0] last_bus_addr; @@ -172,7 +172,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( logic ahbm_clk; logic ahbm_addr_clk; logic ahbm_data_clk; - + // 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); logic [2:0] start_ptr; @@ -184,22 +184,22 @@ module axi4_to_ahb #(parameter TAG = 1) ( if (~found) begin get_nxtbyte_ptr[2:0] = 3'(j); found |= (byteen[j] & (3'(j) >= start_ptr[2:0])) ; - end + end end endfunction // get_nextbyte_ptr - + // Write buffer assign wrbuf_en = axi_awvalid & axi_awready & master_ready; assign wrbuf_data_en = axi_wvalid & axi_wready & master_ready; assign wrbuf_cmd_sent = master_valid & master_ready & (master_opc[2:1] == 2'b01); assign wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en; - + assign axi_awready = ~(wrbuf_vld & ~wrbuf_cmd_sent) & master_ready; assign axi_wready = ~(wrbuf_data_vld & ~wrbuf_cmd_sent) & master_ready; - assign axi_arready = ~(wrbuf_vld & wrbuf_data_vld) & master_ready; + assign axi_arready = ~(wrbuf_vld & wrbuf_data_vld) & master_ready; assign axi_rlast = 1'b1; - + assign wr_cmd_vld = (wrbuf_vld & wrbuf_data_vld); assign master_valid = wr_cmd_vld | axi_arvalid; assign master_tag[TAG-1:0] = wr_cmd_vld ? wrbuf_tag[TAG-1:0] : axi_arid[TAG-1:0]; @@ -207,21 +207,21 @@ module axi4_to_ahb #(parameter TAG = 1) ( assign master_addr[31:0] = wr_cmd_vld ? wrbuf_addr[31:0] : axi_araddr[31:0]; assign master_size[2:0] = wr_cmd_vld ? wrbuf_size[2:0] : axi_arsize[2:0]; assign master_wdata[63:0] = wrbuf_data[63:0]; - + // AXI response channel signals assign axi_bvalid = slave_valid & slave_ready & slave_opc[3]; - assign axi_bresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0); + assign axi_bresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0); assign axi_bid[TAG-1:0] = slave_tag[TAG-1:0]; - - assign axi_rvalid = slave_valid & slave_ready & (slave_opc[3:2] == 2'b0); - assign axi_rresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0); + + assign axi_rvalid = slave_valid & slave_ready & (slave_opc[3:2] == 2'b0); + assign axi_rresp[1:0] = slave_opc[0] ? 2'b10 : (slave_opc[1] ? 2'b11 : 2'b0); assign axi_rid[TAG-1:0] = slave_tag[TAG-1:0]; - assign axi_rdata[63:0] = slave_rdata[63:0]; + assign axi_rdata[63:0] = slave_rdata[63:0]; assign slave_ready = axi_bready & axi_rready; - + // Clock header logic assign bus_write_clk_en = bus_clk_en & ((axi_awvalid & axi_awready) | (axi_wvalid & axi_wready)); - + rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*); rvclkhdr bus_write_cgc (.en(bus_write_clk_en), .l1clk(bus_write_clk), .*); @@ -238,14 +238,14 @@ module axi4_to_ahb #(parameter TAG = 1) ( cmd_done = 1'b0; trxn_done = 1'b0; buf_cmd_byte_ptr_en = 1'b0; - buf_cmd_byte_ptr[2:0] = '0; - slave_valid_pre = 1'b0; + buf_cmd_byte_ptr[2:0] = '0; + slave_valid_pre = 1'b0; master_ready = 1'b0; ahb_htrans[1:0] = 2'b0; slvbuf_wr_en = 1'b0; bypass_en = 1'b0; rd_bypass_idle = 1'b0; - + case (buf_state) IDLE: begin master_ready = 1'b1; @@ -261,11 +261,11 @@ module axi4_to_ahb #(parameter TAG = 1) ( ahb_htrans[1:0] = {2{bypass_en}} & 2'b10; end CMD_RD: begin - buf_nxtstate = (master_valid & (master_opc[2:0] == 3'b000))? STREAM_RD : DATA_RD; + buf_nxtstate = (master_valid & (master_opc[2:0] == 3'b000))? STREAM_RD : DATA_RD; buf_state_en = ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) & ~ahb_hwrite_q; - cmd_done = buf_state_en & ~master_valid; + cmd_done = buf_state_en & ~master_valid; slvbuf_wr_en = buf_state_en; - master_ready = buf_state_en & (buf_nxtstate == STREAM_RD); + master_ready = buf_state_en & (buf_nxtstate == STREAM_RD); buf_wr_en = master_ready; bypass_en = master_ready & master_valid; buf_cmd_byte_ptr[2:0] = {3{bypass_en}} & master_addr[2:0]; @@ -274,7 +274,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( STREAM_RD: begin master_ready = (ahb_hready_q & ~ahb_hresp_q) & ~(master_valid & master_opc[2:1] == 2'b01); buf_wr_en = (master_valid & master_ready & (master_opc[2:0] == 3'b000)); // update the fifo if we are streaming the read commands - buf_nxtstate = ahb_hresp_q ? STREAM_ERR_RD : (buf_wr_en ? STREAM_RD : DATA_RD); // assuming that the master accpets the slave response right away. + buf_nxtstate = ahb_hresp_q ? STREAM_ERR_RD : (buf_wr_en ? STREAM_RD : DATA_RD); // assuming that the master accpets the slave response right away. buf_state_en = (ahb_hready_q | ahb_hresp_q); buf_data_wr_en = buf_state_en; slvbuf_error_in = ahb_hresp_q; @@ -284,7 +284,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( bypass_en = master_ready & master_valid & (buf_nxtstate == STREAM_RD) & buf_state_en; buf_cmd_byte_ptr[2:0] = {3{bypass_en}} & master_addr[2:0]; ahb_htrans[1:0] = 2'b10 & {2{~((buf_nxtstate != STREAM_RD) & buf_state_en)}}; - slvbuf_wr_en = buf_wr_en; // shifting the contents from the buf to slv_buf for streaming cases + slvbuf_wr_en = buf_wr_en; // shifting the contents from the buf to slv_buf for streaming cases end // case: STREAM_RD STREAM_ERR_RD: begin buf_nxtstate = DATA_RD; @@ -309,15 +309,15 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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; - cmd_done = trxn_done & (buf_aligned | (buf_cmd_byte_ptrQ == 3'b111) | + 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)); ahb_htrans[1:0] = {2{~(cmd_done | cmd_doneQ)}} & 2'b10; end DATA_WR: begin buf_state_en = (cmd_doneQ & ahb_hready_q) | ahb_hresp_q; master_ready = buf_state_en & ~ahb_hresp_q & slave_ready; // Ready to accept new command if current command done and no error - buf_nxtstate = (ahb_hresp_q | ~slave_ready) ? DONE : - ((master_valid & master_ready) ? ((master_opc[2:1] == 2'b01) ? CMD_WR : CMD_RD) : IDLE); + buf_nxtstate = (ahb_hresp_q | ~slave_ready) ? DONE : + ((master_valid & master_ready) ? ((master_opc[2:1] == 2'b01) ? CMD_WR : CMD_RD) : IDLE); slvbuf_error_in = ahb_hresp_q; slvbuf_error_en = buf_state_en; @@ -325,7 +325,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( buf_wr_en = buf_state_en & ((buf_nxtstate == CMD_WR) | (buf_nxtstate == CMD_RD)); buf_data_wr_en = buf_wr_en; - cmd_done = (ahb_hresp_q | (ahb_hready_q & (ahb_htrans_q[1:0] != 2'b0) & + 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)))); 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; @@ -333,7 +333,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( 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) : + 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 @@ -357,15 +357,15 @@ module axi4_to_ahb #(parameter TAG = 1) ( ((master_size[1:0] == 2'b01) & ((&wrbuf_byteen[7:6]) | (&wrbuf_byteen[5:4]) | (&wrbuf_byteen[3:2]) | (&wrbuf_byteen[1:0]))) | ((master_size[1:0] == 2'b10) & ((&wrbuf_byteen[7:4]) | (&wrbuf_byteen[3:0]))) | ((master_size[1:0] == 2'b11) & (&wrbuf_byteen[7:0])); - + // Generate the ahb signals assign ahb_haddr[31:0] = bypass_en ? {master_addr[31:3],buf_cmd_byte_ptr[2:0]} : {buf_addr[31:3],buf_cmd_byte_ptr[2:0]}; - // assign ahb_hsize[2:0] = ((buf_state == CMD_RD) | (buf_state == STREAM_RD) | (buf_state == STREAM_ERR_RD) | rd_bypass_idle) ? 3'b011 : + // assign ahb_hsize[2:0] = ((buf_state == CMD_RD) | (buf_state == STREAM_RD) | (buf_state == STREAM_ERR_RD) | rd_bypass_idle) ? 3'b011 : // bypass_en ? {1'b0, ({2{buf_aligned_in}} & buf_size_in[1:0])} : // {1'b0, ({2{buf_aligned}} & buf_size[1:0])}; // Send the full size for aligned trxn assign ahb_hsize[2:0] = bypass_en ? {1'b0, ({2{buf_aligned_in}} & buf_size_in[1:0])} : {1'b0, ({2{buf_aligned}} & buf_size[1:0])}; // Send the full size for aligned trxn - assign ahb_hburst[2:0] = 3'b0; + assign ahb_hburst[2:0] = 3'b0; assign ahb_hmastlock = 1'b0; assign ahb_hprot[3:0] = {3'b001,~axi_arprot[2]}; assign ahb_hwrite = bypass_en ? (master_opc[2:1] == 2'b01) : buf_write; @@ -376,10 +376,10 @@ module axi4_to_ahb #(parameter TAG = 1) ( assign slave_opc[1:0] = {2{slvbuf_error}} & 2'b10; assign slave_rdata[63:0] = slvbuf_error ? {2{last_bus_addr[31:0]}} : ((buf_state == DONE) ? buf_data[63:0] : ahb_hrdata_q[63:0]); assign slave_tag[TAG-1:0] = slvbuf_tag[TAG-1:0]; - + assign last_addr_en = (ahb_htrans[1:0] != 2'b0) & ahb_hready & ahb_hwrite ; - - + + rvdffsc #(.WIDTH(1)) wrbuf_vldff (.din(1'b1), .dout(wrbuf_vld), .en(wrbuf_en), .clear(wrbuf_rst), .clk(bus_clk), .*); rvdffsc #(.WIDTH(1)) wrbuf_data_vldff(.din(1'b1), .dout(wrbuf_data_vld), .en(wrbuf_data_en), .clear(wrbuf_rst), .clk(bus_clk), .*); rvdffs #(.WIDTH(TAG)) wrbuf_tagff (.din(axi_awid[TAG-1:0]), .dout(wrbuf_tag[TAG-1:0]), .en(wrbuf_en), .clk(bus_clk), .*); @@ -389,7 +389,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( rvdffs #(.WIDTH(8)) wrbuf_byteenff (.din(axi_wstrb[7:0]), .dout(wrbuf_byteen[7:0]), .en(wrbuf_data_en), .clk(bus_clk), .*); rvdffs #(.WIDTH(32)) last_bus_addrff (.din(ahb_haddr[31:0]), .dout(last_bus_addr[31:0]), .en(last_addr_en), .clk(ahbm_clk), .*); - + rvdffsc #(.WIDTH($bits(state_t))) buf_state_ff (.din(buf_nxtstate), .dout({buf_state}), .en(buf_state_en), .clear(buf_rst), .clk(ahbm_clk), .*); rvdffs #(.WIDTH(1)) buf_writeff (.din(buf_write_in), .dout(buf_write), .en(buf_wr_en), .clk(buf_clk), .*); rvdffs #(.WIDTH(TAG)) buf_tagff (.din(buf_tag_in[TAG-1:0]), .dout(buf_tag[TAG-1:0]), .en(buf_wr_en), .clk(buf_clk), .*); @@ -398,12 +398,12 @@ module axi4_to_ahb #(parameter TAG = 1) ( rvdffs #(.WIDTH(1)) buf_alignedff (.din(buf_aligned_in), .dout(buf_aligned), .en(buf_wr_en), .clk(buf_clk), .*); rvdffs #(.WIDTH(8)) buf_byteenff (.din(buf_byteen_in[7:0]), .dout(buf_byteen[7:0]), .en(buf_wr_en), .clk(buf_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), .*); - - + + rvdffs #(.WIDTH(1)) slvbuf_writeff (.din(buf_write), .dout(slvbuf_write), .en(slvbuf_wr_en), .clk(buf_clk), .*); rvdffs #(.WIDTH(TAG)) slvbuf_tagff (.din(buf_tag[TAG-1:0]), .dout(slvbuf_tag[TAG-1:0]), .en(slvbuf_wr_en), .clk(buf_clk), .*); rvdffs #(.WIDTH(1)) slvbuf_errorff (.din(slvbuf_error_in), .dout(slvbuf_error), .en(slvbuf_error_en), .clk(ahbm_clk), .*); - + rvdffsc #(.WIDTH(1)) buf_cmd_doneff (.din(1'b1), .en(cmd_done), .dout(cmd_doneQ), .clear(cmd_done_rst), .clk(ahbm_clk), .*); rvdffs #(.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(ahbm_clk), .*); @@ -418,7 +418,7 @@ module axi4_to_ahb #(parameter TAG = 1) ( assign buf_clken = bus_clk_en & (buf_wr_en | slvbuf_wr_en | clk_override); assign ahbm_addr_clken = bus_clk_en & ((ahb_hready & ahb_htrans[1]) | clk_override); assign ahbm_data_clken = bus_clk_en & ((buf_state != IDLE) | clk_override); - + rvclkhdr buf_cgc (.en(buf_clken), .l1clk(buf_clk), .*); rvclkhdr ahbm_cgc (.en(bus_clk_en), .l1clk(ahbm_clk), .*); rvclkhdr ahbm_addr_cgc (.en(ahbm_addr_clken), .l1clk(ahbm_addr_clk), .*); @@ -431,14 +431,14 @@ module axi4_to_ahb #(parameter TAG = 1) ( ((ahb_hsize[2:0] == 3'h2) & (ahb_haddr[1:0] == 2'b0)) | ((ahb_hsize[2:0] == 3'h3) & (ahb_haddr[2:0] == 3'b0))); endproperty - assert_ahb_trxn_aligned: assert property (ahb_trxn_aligned) else + assert_ahb_trxn_aligned: assert property (ahb_trxn_aligned) else $display("Assertion ahb_trxn_aligned failed: ahb_htrans=2'h%h, ahb_hsize=3'h%h, ahb_haddr=32'h%h",ahb_htrans[1:0], ahb_hsize[2:0], ahb_haddr[31:0]); - + property ahb_error_protocol; @(posedge ahbm_clk) (ahb_hready & ahb_hresp) |-> (~$past(ahb_hready) & $past(ahb_hresp)); endproperty assert_ahb_error_protocol: assert property (ahb_error_protocol) else $display("Bus Error with hReady isn't preceded with Bus Error without hready"); `endif - + endmodule // axi4_to_ahb diff --git a/design/lib/beh_lib.sv b/design/lib/beh_lib.sv index ba01eca..fb4e4a0 100644 --- a/design/lib/beh_lib.sv +++ b/design/lib/beh_lib.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,7 +17,7 @@ module rvdff #( parameter WIDTH=1 ) - ( + ( input logic [WIDTH-1:0] din, input logic clk, input logic rst_l, @@ -37,27 +37,27 @@ module rvdff #( parameter WIDTH=1 ) else dout[WIDTH-1:0] <= din[WIDTH-1:0]; end - - -endmodule + + +endmodule // rvdff with 2:1 input mux to flop din iff sel==1 module rvdffs #( parameter WIDTH=1 ) - ( + ( input logic [WIDTH-1:0] din, input logic en, input logic clk, input logic rst_l, output logic [WIDTH-1:0] dout ); - + rvdff #(WIDTH) dffs (.din((en) ? din[WIDTH-1:0] : dout[WIDTH-1:0]), .*); - -endmodule + +endmodule // rvdff with en and clear module rvdffsc #( parameter WIDTH=1 ) - ( + ( input logic [WIDTH-1:0] din, input logic en, input logic clear, @@ -70,24 +70,24 @@ module rvdffsc #( parameter WIDTH=1 ) assign din_new = {WIDTH{~clear}} & (en ? din[WIDTH-1:0] : dout[WIDTH-1:0]); rvdff #(WIDTH) dffsc (.din(din_new[WIDTH-1:0]), .*); -endmodule +endmodule module `TEC_RV_ICG ( input logic TE, E, CP, - output Q + output Q ); logic en_ff; logic enable; - + assign enable = E | TE; `ifdef VERILATOR always @(negedge CP) begin en_ff <= enable; end -`else +`else always @(CP, enable) begin if(!CP) en_ff = enable; @@ -107,16 +107,16 @@ module rvclkhdr logic TE; assign TE = scan_mode; - + `TEC_RV_ICG rvclkhdr ( .*, .E(en), .CP(clk), .Q(l1clk)); endmodule module rvdffe #( parameter WIDTH=1 ) - ( + ( input logic [WIDTH-1:0] din, input logic en, - input logic clk, + input logic clk, input logic rst_l, input logic scan_mode, output logic [WIDTH-1:0] dout @@ -124,36 +124,36 @@ module rvdffe #( parameter WIDTH=1 ) logic l1clk; -`ifndef PHYSICAL +`ifndef PHYSICAL if (WIDTH >= 8) begin: genblock `endif rvclkhdr clkhdr ( .* ); rvdff #(WIDTH) dff (.*, .clk(l1clk)); `ifndef PHYSICAL end - else + else $error("%m: rvdffe width must be >= 8"); `endif - + endmodule // rvdffe module rvsyncss #(parameter WIDTH = 251) - ( + ( input logic clk, input logic rst_l, input logic [WIDTH-1:0] din, - output logic [WIDTH-1:0] dout + output logic [WIDTH-1:0] dout ); - + 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])); - + endmodule // rvsyncss module rvlsadder - ( + ( input logic [31:0] rs1, input logic [11:0] offset, @@ -162,7 +162,7 @@ module rvlsadder logic cout; logic sign; - + logic [31:12] rs1_inc; logic [31:12] rs1_dec; @@ -177,13 +177,13 @@ module rvlsadder assign dout[31:12] = ({20{ sign ^~ cout}} & rs1[31:12]) | ({20{ ~sign & cout}} & rs1_inc[31:12]) | ({20{ sign & ~cout}} & rs1_dec[31:12]); - + endmodule // rvlsadder // assume we only maintain pc[31:1] in the pipe module rvbradder - ( + ( input [31:1] pc, input [12:1] offset, @@ -192,7 +192,7 @@ module rvbradder logic cout; logic sign; - + logic [31:13] pc_inc; logic [31:13] pc_dec; @@ -208,44 +208,44 @@ module rvbradder assign dout[31:13] = ({19{ sign ^~ cout}} & pc[31:13]) | ({19{ ~sign & cout}} & pc_inc[31:13]) | ({19{ sign & ~cout}} & pc_dec[31:13]); - - + + endmodule // rvbradder // 2s complement circuit module rvtwoscomp #( parameter WIDTH=32 ) - ( + ( input logic [WIDTH-1:0] din, output logic [WIDTH-1:0] dout ); - + logic [WIDTH-1:1] dout_temp; // holding for all other bits except for the lsb. LSB is always din - + genvar i; - + for ( i = 1; i < WIDTH; i++ ) begin : flip_after_first_one assign dout_temp[i] = (|din[i-1:0]) ? ~din[i] : din[i]; end : flip_after_first_one - + assign dout[WIDTH-1:0] = { dout_temp[WIDTH-1:1], din[0] }; endmodule // 2'scomp // find first module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) ) - ( + ( input logic [WIDTH-1:0] din, output logic [SHIFT-1:0] dout ); logic done; - + always_comb begin dout[SHIFT-1:0] = {SHIFT{1'b0}}; done = 1'b0; - + for ( int i = WIDTH-1; i > 0; i-- ) begin : find_first_one done |= din[i]; dout[SHIFT-1:0] += done ? 1'b0 : 1'b1; @@ -254,19 +254,19 @@ module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) ) endmodule // rvfindfirst1 module rvfindfirst1hot #( parameter WIDTH=32 ) - ( + ( input logic [WIDTH-1:0] din, output logic [WIDTH-1:0] dout ); logic done; - + always_comb begin dout[WIDTH-1:0] = {WIDTH{1'b0}}; done = 1'b0; for ( int i = 0; i < WIDTH; i++ ) begin : find_first_one dout[i] = ~done & din[i]; - done |= din[i]; + done |= din[i]; end : find_first_one end endmodule // rvfindfirst1hot @@ -274,25 +274,25 @@ 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 ) - ( + ( 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 - output logic match + input logic masken, // when 1 : do mask. 0 : full match + output logic match ); - - logic [WIDTH-1:0] matchvec; + + logic [WIDTH-1:0] matchvec; logic masken_or_fullmask; - + assign masken_or_fullmask = masken & ~(&mask[WIDTH-1:0]); - + assign matchvec[0] = masken_or_fullmask | (mask[0] == data[0]); genvar i; - + for ( i = 1; i < WIDTH; i++ ) begin : match_after_first_zero assign matchvec[i] = (&mask[i-1:0] & masken_or_fullmask) ? 1'b1 : (mask[i] == data[i]); end : match_after_first_zero - + assign match = &matchvec[WIDTH-1:0]; // all bits either matched or were masked off endmodule // rvmaskandmatch @@ -302,17 +302,17 @@ module rvbtb_tag_hash ( output logic [`RV_BTB_BTAG_SIZE-1:0] hash ); `ifndef RV_BTB_BTAG_FOLD - assign hash = {(pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+1] ^ - pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^ + assign hash = {(pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE+1] ^ + pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^ pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+1])}; `else assign hash = {( - pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^ + pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE+1] ^ pc[`RV_BTB_ADDR_HI+`RV_BTB_BTAG_SIZE:`RV_BTB_ADDR_HI+1])}; `endif - -// assign hash = {pc[`RV_BTB_ADDR_HI+1],(pc[`RV_BTB_ADDR_HI+13:`RV_BTB_ADDR_HI+10] ^ -// pc[`RV_BTB_ADDR_HI+9:`RV_BTB_ADDR_HI+6] ^ + +// assign hash = {pc[`RV_BTB_ADDR_HI+1],(pc[`RV_BTB_ADDR_HI+13:`RV_BTB_ADDR_HI+10] ^ +// pc[`RV_BTB_ADDR_HI+9:`RV_BTB_ADDR_HI+6] ^ // pc[`RV_BTB_ADDR_HI+5:`RV_BTB_ADDR_HI+2])}; endmodule @@ -322,12 +322,12 @@ module rvbtb_addr_hash ( output logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] hash ); - assign hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = pc[`RV_BTB_INDEX1_HI:`RV_BTB_INDEX1_LO] ^ + assign hash[`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] = pc[`RV_BTB_INDEX1_HI:`RV_BTB_INDEX1_LO] ^ -`ifndef RV_BTB_FOLD2_INDEX_HASH - pc[`RV_BTB_INDEX2_HI:`RV_BTB_INDEX2_LO] ^ +`ifndef RV_BTB_FOLD2_INDEX_HASH + pc[`RV_BTB_INDEX2_HI:`RV_BTB_INDEX2_LO] ^ `endif - + pc[`RV_BTB_INDEX3_HI:`RV_BTB_INDEX3_LO]; endmodule @@ -347,10 +347,10 @@ endmodule // Check if the S_ADDR <= addr < E_ADDR module rvrangecheck #(CCM_SADR = 32'h0, - CCM_SIZE = 128) ( + 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 + output logic in_region ); localparam REGION_BITS = 4; @@ -358,42 +358,42 @@ module rvrangecheck #(CCM_SADR = 32'h0, logic [31:0] start_addr; logic [3:0] region; - + assign start_addr[31:0] = CCM_SADR; assign region[REGION_BITS-1:0] = start_addr[31:(32-REGION_BITS)]; - assign in_region = (addr[31:(32-REGION_BITS)] == region[REGION_BITS-1:0]); + 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]); - + 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 ); - + assign parity_out = ^(data_in[WIDTH-1:0]) ; - + 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 ); - + assign parity_err = ^(data_in[WIDTH-1:0]) ^ parity_in ; - + endmodule // rveven_paritycheck module rvecc_encode ( input [31:0] din, output [6:0] ecc_out - ); + ); logic [5:0] ecc_out_temp; assign ecc_out_temp[0] = din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30]; @@ -422,7 +422,7 @@ module rvecc_decode ( logic [6:0] ecc_check; logic [38:0] error_mask; logic [38:0] din_plus_parity, dout_plus_parity; - + // Generate the ecc bits assign ecc_check[0] = ecc_in[0]^din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30]; assign ecc_check[1] = ecc_in[1]^din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31]; @@ -435,8 +435,8 @@ module rvecc_decode ( assign ecc_check[6] = ((^din[31:0])^(^ecc_in[6:0])) & ~sed_ded; assign single_ecc_error = en & (ecc_check[6:0] != 0) & ecc_check[6]; // this will never be on for sed_ded - assign double_ecc_error = en & (ecc_check[6:0] != 0) & ~ecc_check[6]; // all errors in the sed_ded case will be recorded as DE - + assign double_ecc_error = en & (ecc_check[6:0] != 0) & ~ecc_check[6]; // all errors in the sed_ded case will be recorded as DE + // Generate the mask for error correctiong for (genvar i=1; i<40; i++) begin assign error_mask[i-1] = (ecc_check[5:0] == i); @@ -444,9 +444,9 @@ module rvecc_decode ( // 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 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]}; - + endmodule // rvecc_decode diff --git a/design/lib/mem_lib.sv b/design/lib/mem_lib.sv index daa8cab..89395b2 100644 --- a/design/lib/mem_lib.sv +++ b/design/lib/mem_lib.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,14 +17,14 @@ //=================================== START OF CCM ======================================================================= //============= Possible sram sizes for a 39 bit wide memory ( 4 bytes + 7 bits ECC ) ===================================== //------------------------------------------------------------------------------------------------------------------------- -module ram_32768x39 +module ram_32768x39 ( input logic CLK, input logic [14:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [32767:0]; @@ -35,20 +35,20 @@ module ram_32768x39 Q <= ram_core[ADR]; end - + endmodule // ram_32768x39 -module ram_16384x39 +module ram_16384x39 ( input logic CLK, input logic [13:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [16383:0]; @@ -59,19 +59,19 @@ module ram_16384x39 Q <= ram_core[ADR]; end - + endmodule // ram_16384x39 -module ram_8192x39 +module ram_8192x39 ( input logic CLK, input logic [12:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [8191:0]; @@ -82,19 +82,19 @@ module ram_8192x39 Q <= ram_core[ADR]; end - + endmodule // ram_8192x39 -module ram_4096x39 +module ram_4096x39 ( input logic CLK, input logic [11:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [4095:0]; @@ -105,19 +105,19 @@ module ram_4096x39 Q <= ram_core[ADR]; end - + endmodule // ram_4096x39 -module ram_3072x39 +module ram_3072x39 ( input logic CLK, input logic [11:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [3071:0]; @@ -128,21 +128,21 @@ module ram_3072x39 Q <= ram_core[ADR]; end - + endmodule // ram_3072x39 -module ram_2048x39 +module ram_2048x39 ( input logic CLK, input logic [10:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [2047:0]; @@ -153,7 +153,7 @@ module ram_2048x39 Q <= ram_core[ADR]; end - + endmodule // ram_2048x39 @@ -165,7 +165,7 @@ module ram_1536x39 // need this for the 48KB DCCM option output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [1535:0]; @@ -176,20 +176,20 @@ module ram_1536x39 // need this for the 48KB DCCM option Q <= ram_core[ADR]; end - + endmodule // ram_1536x39 -module ram_1024x39 +module ram_1024x39 ( input logic CLK, input logic [9:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [1023:0]; @@ -200,19 +200,19 @@ module ram_1024x39 Q <= ram_core[ADR]; end - + endmodule // ram_1024x39 -module ram_768x39 +module ram_768x39 ( input logic CLK, input logic [9:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [767:0]; @@ -223,20 +223,20 @@ module ram_768x39 Q <= ram_core[ADR]; end - + endmodule // ram_768x39 -module ram_512x39 +module ram_512x39 ( input logic CLK, input logic [8:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [511:0]; @@ -247,20 +247,20 @@ module ram_512x39 Q <= ram_core[ADR]; end - + endmodule // ram_512x39 -module ram_256x39 +module ram_256x39 ( input logic CLK, input logic [7:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [255:0]; @@ -271,20 +271,20 @@ module ram_256x39 Q <= ram_core[ADR]; end - + endmodule // ram_512x39 -module ram_128x39 +module ram_128x39 ( input logic CLK, input logic [6:0] ADR, input logic [38:0] D, output logic [38:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [38:0] ram_core [127:0]; @@ -295,7 +295,7 @@ module ram_128x39 Q <= ram_core[ADR]; end - + endmodule // ram_128x39 @@ -303,7 +303,7 @@ endmodule // ram_128x39 //========================================================================================================================= //=================================== START OF TAGS ======================================================================= // I CACHE TAGS -module ram_1024x20 +module ram_1024x20 ( input logic CLK, input logic [9:0] ADR, @@ -311,7 +311,7 @@ module ram_1024x20 output logic [19:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [19:0] ram_core [1023:0]; @@ -322,18 +322,18 @@ module ram_1024x20 Q <= ram_core[ADR]; end - + endmodule // ram_1024x20 -module ram_512x20 +module ram_512x20 ( input logic CLK, input logic [8:0] ADR, input logic [19:0] D, output logic [19:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [19:0] ram_core [511:0]; @@ -349,14 +349,14 @@ module ram_512x20 endmodule // ram_512x20 -module ram_256x20 +module ram_256x20 ( input logic CLK, input logic [7:0] ADR, input logic [19:0] D, output logic [19:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [19:0] ram_core [255:0]; @@ -371,14 +371,14 @@ module ram_256x20 endmodule // ram_256x20 -module ram_128x20 +module ram_128x20 ( input logic CLK, input logic [6:0] ADR, input logic [19:0] D, output logic [19:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [19:0] ram_core [127:0]; @@ -394,14 +394,14 @@ module ram_128x20 endmodule // ram_128x20 -module ram_64x20 +module ram_64x20 ( input logic CLK, input logic [5:0] ADR, input logic [19:0] D, output logic [19:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [19:0] ram_core [63:0]; @@ -421,14 +421,14 @@ endmodule // ram_64x20 // 4096 x 34 -module ram_4096x34 +module ram_4096x34 ( input logic CLK, input logic [11:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [4095:0]; @@ -440,20 +440,20 @@ module ram_4096x34 end - + endmodule // ram_4096x34 -// 2048x34 -module ram_2048x34 +// 2048x34 +module ram_2048x34 ( input logic CLK, input logic [10:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [2047:0]; @@ -465,20 +465,20 @@ module ram_2048x34 end - + endmodule // ram_2048x34 -// 1024x34 -module ram_1024x34 +// 1024x34 +module ram_1024x34 ( input logic CLK, input logic [9:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [1023:0]; @@ -490,20 +490,20 @@ module ram_1024x34 end - + endmodule // ram_1024x34 -// 512x34 -module ram_512x34 +// 512x34 +module ram_512x34 ( input logic CLK, input logic [8:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [511:0]; @@ -515,20 +515,20 @@ module ram_512x34 end - + endmodule // ram_512x34 -// 256x34 -module ram_256x34 +// 256x34 +module ram_256x34 ( input logic CLK, input logic [7:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [255:0]; @@ -540,20 +540,20 @@ module ram_256x34 end - + endmodule // ram_256x34 -// 128x34 -module ram_128x34 +// 128x34 +module ram_128x34 ( input logic CLK, input logic [6:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [127:0]; @@ -569,15 +569,15 @@ module ram_128x34 endmodule // ram_128x34 -// 64x34 -module ram_64x34 +// 64x34 +module ram_64x34 ( input logic CLK, input logic [5:0] ADR, input logic [33:0] D, output logic [33:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [33:0] ram_core [63:0]; @@ -595,16 +595,16 @@ endmodule // ram_64x34 // New SRAMS for ECC; ECC on 16b boundaries -// 4096x44 -module ram_4096x42 +// 4096x44 +module ram_4096x42 ( input logic CLK, input logic [11:0] ADR, input logic [41:0] D, output logic [41:0] Q, - + input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [4095:0]; @@ -621,15 +621,15 @@ module ram_4096x42 endmodule // ram_4096x42 -// 2048x44 -module ram_2048x42 +// 2048x44 +module ram_2048x42 ( input logic CLK, input logic [10:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [2047:0]; @@ -645,15 +645,15 @@ module ram_2048x42 endmodule // ram_2048x42 -// 1024x44 -module ram_1024x42 +// 1024x44 +module ram_1024x42 ( input logic CLK, input logic [9:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [1023:0]; @@ -669,15 +669,15 @@ module ram_1024x42 endmodule // ram_1024x42 -// 512x44 -module ram_512x42 +// 512x44 +module ram_512x42 ( input logic CLK, input logic [8:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [511:0]; @@ -689,21 +689,21 @@ module ram_512x42 end - + endmodule // ram_512x42 -// 256x42 -module ram_256x42 +// 256x42 +module ram_256x42 ( input logic CLK, input logic [7:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [255:0]; @@ -715,20 +715,20 @@ module ram_256x42 end - + endmodule // ram_256x42 -// 128x42 -module ram_128x42 +// 128x42 +module ram_128x42 ( input logic CLK, input logic [6:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [127:0]; @@ -740,20 +740,20 @@ module ram_128x42 end - + endmodule // ram_128x42 -// 64x42 -module ram_64x42 +// 64x42 +module ram_64x42 ( input logic CLK, input logic [5:0] ADR, input logic [41:0] D, output logic [41:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [41:0] ram_core [63:0]; @@ -772,8 +772,8 @@ endmodule // ram_64x42 // START TAGS -// 1024x21 -module ram_1024x21 +// 1024x21 +module ram_1024x21 ( input logic CLK, input logic [9:0] ADR, input logic [20:0] D, @@ -781,7 +781,7 @@ module ram_1024x21 output logic [20:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [20:0] ram_core [1023:0]; @@ -796,15 +796,15 @@ module ram_1024x21 endmodule // ram_1024x21 -// 512x21 -module ram_512x21 +// 512x21 +module ram_512x21 ( input logic CLK, input logic [8:0] ADR, input logic [20:0] D, output logic [20:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [20:0] ram_core [511:0]; @@ -816,21 +816,21 @@ module ram_512x21 end - + endmodule // ram_512x21 -// 256x21 -module ram_256x21 +// 256x21 +module ram_256x21 ( input logic CLK, input logic [7:0] ADR, input logic [20:0] D, output logic [20:0] Q, input logic WE ); - - // behavior to be replaced by actual SRAM in VLE + + // behavior to be replaced by actual SRAM in VLE reg [20:0] ram_core [255:0]; @@ -841,20 +841,20 @@ module ram_256x21 end - + endmodule // ram_256x21 -// 128x21 -module ram_128x21 +// 128x21 +module ram_128x21 ( input logic CLK, input logic [6:0] ADR, input logic [20:0] D, output logic [20:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [20:0] ram_core [127:0]; @@ -866,13 +866,13 @@ module ram_128x21 end - + endmodule // ram_128x21 -// 64x21 -module ram_64x21 +// 64x21 +module ram_64x21 ( input logic CLK, input logic [5:0] ADR, input logic [20:0] D, @@ -893,17 +893,17 @@ module ram_64x21 endmodule // ram_64x21 -// New tag rams for ECC. +// New tag rams for ECC. -// 1024x25 -module ram_1024x25 +// 1024x25 +module ram_1024x25 ( input logic CLK, input logic [9:0] ADR, input logic [24:0] D, output logic [24:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [24:0] ram_core [1023:0]; @@ -915,13 +915,13 @@ module ram_1024x25 end - + endmodule // ram_1024x25 -// 512x25 -module ram_512x25 +// 512x25 +module ram_512x25 ( input logic CLK, input logic [8:0] ADR, input logic [24:0] D, @@ -929,7 +929,7 @@ module ram_512x25 output logic [24:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [24:0] ram_core [511:0]; @@ -941,13 +941,13 @@ module ram_512x25 end - + endmodule // ram_512x25 -// 256x25 -module ram_256x25 +// 256x25 +module ram_256x25 ( input logic CLK, input logic [7:0] ADR, input logic [24:0] D, @@ -955,8 +955,8 @@ module ram_256x25 output logic [24:0] Q, input logic WE ); - - // behavior to be replaced by actual SRAM in VLE + + // behavior to be replaced by actual SRAM in VLE reg [24:0] ram_core [255:0]; @@ -967,13 +967,13 @@ module ram_256x25 end - + endmodule // ram_256x25 -// 128x25 -module ram_128x25 +// 128x25 +module ram_128x25 ( input logic CLK, input logic [6:0] ADR, input logic [24:0] D, @@ -981,7 +981,7 @@ module ram_128x25 output logic [24:0] Q, input logic WE ); - + // behavior to be replaced by actual SRAM in VLE reg [24:0] ram_core [127:0]; @@ -993,13 +993,13 @@ module ram_128x25 end - + endmodule // ram_128x25 -// 64x25 -module ram_64x25 +// 64x25 +module ram_64x25 ( input logic CLK, input logic [5:0] ADR, input logic [24:0] D, @@ -1019,7 +1019,7 @@ module ram_64x25 end - + endmodule // ram_64x25 diff --git a/design/lsu/lsu.sv b/design/lsu/lsu.sv index 282be0c..403a8ae 100644 --- a/design/lsu/lsu.sv +++ b/design/lsu/lsu.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,13 +16,13 @@ //******************************************************************************** // $Id$ // -// +// // Function: Top level file for load store unit // Comments: // -// +// // DC1 -> DC2 -> DC3 -> DC4 (Commit) -// +// //******************************************************************************** module lsu @@ -32,23 +32,23 @@ module lsu input logic [31:0] i0_result_e4_eff, // I0 e4 result for e4 -> dc3 store forwarding input logic [31:0] i1_result_e4_eff, // I1 e4 result for e4 -> dc3 store forwarding input logic [31:0] i0_result_e2, // I0 e2 result for e2 -> dc2 store forwarding - - input logic flush_final_e3, // I0/I1 flush in e3 + + input logic flush_final_e3, // I0/I1 flush in e3 input logic i0_flush_final_e3, // I0 flush in e3 input logic dec_tlu_flush_lower_wb, // I0/I1 writeback flush. This is used to flush the old packets only - input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state - input logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state + input logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state + input logic dec_tlu_i1_kill_writeb_wb, // I1 is flushed, don't writeback any results to arch state // chicken signals input logic dec_tlu_non_blocking_disable, // disable the non block input logic dec_tlu_wb_coalescing_disable, // disable the write buffer coalesce - input logic dec_tlu_ld_miss_byp_wb_disable, // disable the miss bypass in the write buffer + input logic dec_tlu_ld_miss_byp_wb_disable, // disable the miss bypass in the write buffer input logic dec_tlu_core_ecc_disable, // disable the generation of the ecc input logic [31:0] exu_lsu_rs1_d, // address rs operand input logic [31:0] exu_lsu_rs2_d, // store data input logic [11:0] dec_lsu_offset_d, // address offset operand - + input lsu_pkt_t lsu_p, // lsu control packet input logic dec_i0_lsu_decode_d, // lsu is in i0 input logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control @@ -57,7 +57,7 @@ module lsu output logic lsu_freeze_dc3, // lsu freeze due to load to external output logic lsu_store_stall_any, // This is for blocking stores in the decode output logic lsu_idle_any, // lsu buffers are empty and no instruction in the pipeline - + output lsu_error_pkt_t lsu_error_pkt_dc3, // lsu exception packet output logic lsu_freeze_external_ints_dc3, // freeze due to sideeffects loads need to suppress external interrupt output logic lsu_imprecise_error_load_any, // bus load imprecise error @@ -65,25 +65,25 @@ module lsu output logic [31:0] lsu_imprecise_error_addr_any, // bus store imprecise error address // Non-blocking loads - input logic dec_nonblock_load_freeze_dc2, // + input logic dec_nonblock_load_freeze_dc2, // output logic lsu_nonblock_load_valid_dc3, // there is an external load -> put in the cam output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // the tag of the external non block load output logic lsu_nonblock_load_inv_dc5, // invalidate signal for the cam entry for non block loads output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // tag of the enrty which needs to be invalidated - output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam - output logic lsu_nonblock_load_data_error, // non block load has an error - output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error + output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam + output logic lsu_nonblock_load_data_error, // non block load has an error + output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error output logic [31:0] lsu_nonblock_load_data, // Data of the non block load output logic lsu_pmu_misaligned_dc3, // PMU : misaligned - output logic lsu_pmu_bus_trxn, // PMU : bus transaction + output logic lsu_pmu_bus_trxn, // PMU : bus transaction output logic lsu_pmu_bus_misaligned, // PMU : misaligned access going to the bus output logic lsu_pmu_bus_error, // PMU : bus sending error back output logic lsu_pmu_bus_busy, // PMU : bus is not ready // Trigger signals input trigger_pkt_t [3:0] trigger_pkt_any, // Trigger info from the decode - output logic [3:0] lsu_trigger_match_dc3, // lsu trigger hit (one bit per trigger) + output logic [3:0] lsu_trigger_match_dc3, // lsu trigger hit (one bit per trigger) // DCCM ports output logic dccm_wren, // DCCM write enable @@ -92,7 +92,7 @@ module lsu output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_lo, // DCCM read address low bank output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_hi, // DCCM read address hi bank (hi and low same if aligned read) output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_wr_data, // DCCM write data (this is always aligned) - + input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // DCCM read data low bank input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // DCCM read data hi bank @@ -104,7 +104,7 @@ module lsu output logic [31:0] picm_wr_data, // PIC memory write data input logic [31:0] picm_rd_data, // PIC memory read/mask data - // AXI signals + // AXI signals // AXI Write Channels output logic lsu_axi_awvalid, input logic lsu_axi_awready, @@ -118,19 +118,19 @@ module lsu output logic [3:0] lsu_axi_awcache, output logic [2:0] lsu_axi_awprot, output logic [3:0] lsu_axi_awqos, - - output logic lsu_axi_wvalid, + + output logic lsu_axi_wvalid, input logic lsu_axi_wready, output logic [63:0] lsu_axi_wdata, output logic [7:0] lsu_axi_wstrb, output logic lsu_axi_wlast, - + input logic lsu_axi_bvalid, output logic lsu_axi_bready, input logic [1:0] lsu_axi_bresp, input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic lsu_axi_arvalid, input logic lsu_axi_arready, output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid, @@ -143,16 +143,16 @@ module lsu output logic [3:0] lsu_axi_arcache, output logic [2:0] lsu_axi_arprot, output logic [3:0] lsu_axi_arqos, - + input logic lsu_axi_rvalid, output logic lsu_axi_rready, input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid, input logic [63:0] lsu_axi_rdata, input logic [1:0] lsu_axi_rresp, input logic lsu_axi_rlast, - + input logic lsu_bus_clk_en, // external drives a clock_en to control bus ratio - + // DMA slave input logic dma_dccm_req, // DMA read/write to dccm input logic [31:0] dma_mem_addr, // DMA address @@ -167,15 +167,15 @@ module lsu input logic clk_override, // Disable clock gating input logic scan_mode, // scan - input logic clk, + input logic clk, input logic free_clk, input logic rst_l ); - + `include "global.h" - + logic lsu_dccm_rden_dc3; logic [63:0] store_data_dc2; logic [63:0] store_data_dc3; @@ -187,7 +187,7 @@ module lsu logic single_ecc_error_hi_dc3, single_ecc_error_lo_dc3; logic lsu_single_ecc_error_dc3, lsu_single_ecc_error_dc4, lsu_single_ecc_error_dc5; logic lsu_double_ecc_error_dc3; - + logic [31:0] dccm_data_hi_dc3; logic [31:0] dccm_data_lo_dc3; logic [6:0] dccm_data_ecc_hi_dc3; @@ -195,13 +195,13 @@ module lsu logic [31:0] lsu_ld_data_dc3; logic [31:0] picm_mask_data_dc3; - + logic [31:0] lsu_addr_dc1, lsu_addr_dc2, lsu_addr_dc3, lsu_addr_dc4, lsu_addr_dc5; logic [31:0] end_addr_dc1, end_addr_dc2, end_addr_dc3, end_addr_dc4, end_addr_dc5; lsu_pkt_t lsu_pkt_dc1, lsu_pkt_dc2, lsu_pkt_dc3, lsu_pkt_dc4, lsu_pkt_dc5; logic lsu_i0_valid_dc1, lsu_i0_valid_dc2, lsu_i0_valid_dc3, lsu_i0_valid_dc4, lsu_i0_valid_dc5; - + // Store Buffer signals logic isldst_dc1, isldst_dc2, isldst_dc3; logic store_stbuf_reqvld_dc3; @@ -221,7 +221,7 @@ module lsu logic [LSU_SB_BITS-1:0] stbuf_addr_any; logic [DCCM_DATA_WIDTH-1:0] stbuf_data_any; logic [(DCCM_FDATA_WIDTH-DCCM_DATA_WIDTH-1):0] stbuf_ecc_any; - + logic lsu_cmpen_dc2; logic [DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3; logic [DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3; @@ -242,45 +242,45 @@ module lsu logic [31:0] bus_read_data_dc3; logic ld_bus_error_dc3; logic [31:0] ld_bus_error_addr_dc3; - + logic flush_dc2_up, flush_dc3, flush_dc4, flush_dc5, flush_prior_dc5; logic is_sideeffects_dc2, is_sideeffects_dc3; logic ldst_nodma_dc1todc3; // Clocks - logic lsu_c1_dc3_clk, lsu_c1_dc4_clk, lsu_c1_dc5_clk; - logic lsu_c2_dc3_clk, lsu_c2_dc4_clk, lsu_c2_dc5_clk; - logic lsu_freeze_c1_dc1_clk, lsu_freeze_c1_dc2_clk, lsu_freeze_c1_dc3_clk; + logic lsu_c1_dc3_clk, lsu_c1_dc4_clk, lsu_c1_dc5_clk; + logic lsu_c2_dc3_clk, lsu_c2_dc4_clk, lsu_c2_dc5_clk; + logic lsu_freeze_c1_dc1_clk, lsu_freeze_c1_dc2_clk, lsu_freeze_c1_dc3_clk; logic lsu_store_c1_dc1_clk, lsu_store_c1_dc2_clk, lsu_store_c1_dc3_clk, lsu_store_c1_dc4_clk, lsu_store_c1_dc5_clk; - - logic lsu_freeze_c2_dc1_clk, lsu_freeze_c2_dc2_clk, lsu_freeze_c2_dc3_clk, lsu_freeze_c2_dc4_clk; + + logic lsu_freeze_c2_dc1_clk, lsu_freeze_c2_dc2_clk, lsu_freeze_c2_dc3_clk, lsu_freeze_c2_dc4_clk; logic lsu_stbuf_c1_clk; logic lsu_rdbuf_c1_clk, lsu_wrbuf_c1_clk; logic lsu_dccm_c1_dc3_clk, lsu_pic_c1_dc3_clk; logic lsu_busm_clk; logic lsu_free_c2_clk; - + lsu_lsc_ctl lsu_lsc_ctl(.*); - + // block stores in decode - for either bus or stbuf reasons assign lsu_store_stall_any = lsu_stbuf_full_any | lsu_write_buffer_full_any; - + // Ready to accept dma trxns // There can't be any inpipe forwarding from non-dma packet to dma packet since they can be flushed so we can't have ld/st in dc3-dc5 when dma is in dc2 assign ldst_nodma_dc1todc3 = (lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma) | (lsu_pkt_dc2.valid & ~lsu_pkt_dc2.dma) | (lsu_pkt_dc3.valid & ~lsu_pkt_dc3.dma); assign dccm_ready = ~(lsu_p.valid | lsu_stbuf_full_any | lsu_freeze_dc3 | ldst_nodma_dc1todc3); - + // Generate per cycle flush signals assign flush_dc2_up = flush_final_e3 | i0_flush_final_e3 | dec_tlu_flush_lower_wb; assign flush_dc3 = (flush_final_e3 & i0_flush_final_e3) | dec_tlu_flush_lower_wb; assign flush_dc4 = dec_tlu_flush_lower_wb; assign flush_dc5 = (dec_tlu_i0_kill_writeb_wb | (dec_tlu_i1_kill_writeb_wb & ~lsu_i0_valid_dc5)); assign flush_prior_dc5 = dec_tlu_i0_kill_writeb_wb & ~lsu_i0_valid_dc5; // Flush is due to i0 instruction and ld/st is in i1 - + // lsu idle - assign lsu_idle_any = ~(lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.valid) & + assign lsu_idle_any = ~(lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.valid) & lsu_read_buffer_empty_any & lsu_write_buffer_empty_any & lsu_stbuf_empty_any; // Instantiate the store buffer @@ -292,7 +292,7 @@ module lsu assign isldst_dc1 = lsu_pkt_dc1.valid & (lsu_pkt_dc1.load | lsu_pkt_dc1.store); assign isldst_dc2 = lsu_pkt_dc2.valid & (lsu_pkt_dc2.load | lsu_pkt_dc2.store); assign isldst_dc3 = lsu_pkt_dc3.valid & (lsu_pkt_dc3.load | lsu_pkt_dc3.store) & (addr_in_dccm_dc3 | addr_in_pic_dc3); - + // Disable Forwarding for now assign lsu_cmpen_dc2 = lsu_pkt_dc2.valid & (lsu_pkt_dc2.load | lsu_pkt_dc2.store) & addr_in_dccm_dc2; @@ -302,14 +302,14 @@ module lsu // PMU signals assign lsu_pmu_misaligned_dc3 = lsu_pkt_dc3.valid & ((lsu_pkt_dc3.half & lsu_addr_dc3[0]) | (lsu_pkt_dc3.word & (|lsu_addr_dc3[1:0]))); - + lsu_dccm_ctl dccm_ctl ( .lsu_addr_dc1(lsu_addr_dc1[31:0]), .end_addr_dc1(end_addr_dc1[DCCM_BITS-1:0]), .lsu_addr_dc3(lsu_addr_dc3[DCCM_BITS-1:0]), .* ); - + lsu_stbuf stbuf( .lsu_addr_dc1(lsu_addr_dc1[LSU_SB_BITS-1:0]), .end_addr_dc1(end_addr_dc1[LSU_SB_BITS-1:0]), @@ -318,9 +318,9 @@ module lsu .lsu_addr_dc3(lsu_addr_dc3[LSU_SB_BITS-1:0]), .end_addr_dc3(end_addr_dc3[LSU_SB_BITS-1:0]), .* - + ); - + lsu_ecc ecc ( .lsu_addr_dc3(lsu_addr_dc3[DCCM_BITS-1:0]), .end_addr_dc3(end_addr_dc3[DCCM_BITS-1:0]), @@ -331,13 +331,13 @@ module lsu .store_data_dc3(store_data_dc3[31:0]), .* ); - + // Clk domain lsu_clkdomain clkdomain (.*); // Bus interface lsu_bus_intf bus_intf (.*); - + //Flops //rvdffs #(1) lsu_i0_valid_dc1ff (.*, .din(dec_i0_lsu_decode_d), .dout(lsu_i0_valid_dc1), .en(~lsu_freeze_dc3)); rvdff #(1) lsu_i0_valid_dc1ff (.*, .din(dec_i0_lsu_decode_d), .dout(lsu_i0_valid_dc1), .clk(lsu_freeze_c2_dc1_clk)); @@ -345,9 +345,9 @@ module lsu rvdff #(1) lsu_i0_valid_dc3ff (.*, .din(lsu_i0_valid_dc2), .dout(lsu_i0_valid_dc3), .clk(lsu_freeze_c2_dc3_clk)); rvdff #(1) lsu_i0_valid_dc4ff (.*, .din(lsu_i0_valid_dc3), .dout(lsu_i0_valid_dc4), .clk(lsu_freeze_c2_dc4_clk)); rvdff #(1) lsu_i0_valid_dc5ff (.*, .din(lsu_i0_valid_dc4), .dout(lsu_i0_valid_dc5), .clk(lsu_c2_dc5_clk)); - rvdff #(1) lsu_single_ecc_err_dc4(.*, .din(lsu_single_ecc_error_dc3), .dout(lsu_single_ecc_error_dc4), .clk(lsu_c2_dc4_clk)); + rvdff #(1) lsu_single_ecc_err_dc4(.*, .din(lsu_single_ecc_error_dc3), .dout(lsu_single_ecc_error_dc4), .clk(lsu_c2_dc4_clk)); rvdff #(1) lsu_single_ecc_err_dc5(.*, .din(lsu_single_ecc_error_dc4), .dout(lsu_single_ecc_error_dc5), .clk(lsu_c2_dc5_clk)); - + `ifdef ASSERT_ON logic [8:0] store_data_bypass_sel; assign store_data_bypass_sel[8:0] = {lsu_p.store_data_bypass_c1, @@ -358,8 +358,8 @@ module lsu lsu_p.store_data_bypass_e4_c3[1:0]}; assert_store_data_bypass_onehot: assert #0 ($onehot0(store_data_bypass_sel[8:0])); - assert_picm_rden_and_wren: assert #0 ($onehot0({(picm_rden | picm_mken),picm_wren})); - assert_picm_rden_and_dccmen: assert #0 ($onehot0({(picm_rden | picm_mken),dccm_rden})); + assert_picm_rden_and_wren: assert #0 ($onehot0({(picm_rden | picm_mken),picm_wren})); + assert_picm_rden_and_dccmen: assert #0 ($onehot0({(picm_rden | picm_mken),dccm_rden})); assert_picm_wren_and_dccmen: assert #0 ($onehot0({picm_wren, dccm_wren})); //assert_no_exceptions: assert #0 (lsu_exc_pkt_dc3.exc_valid == 1'b0); @@ -369,5 +369,5 @@ module lsu assert_exception_no_lsu_flush: assert property (exception_no_lsu_flush) else $display("No flush within 2 cycles of exception"); `endif - + endmodule // lsu diff --git a/design/lsu/lsu_addrcheck.sv b/design/lsu/lsu_addrcheck.sv index 31c04bc..c81b05f 100644 --- a/design/lsu/lsu_addrcheck.sv +++ b/design/lsu/lsu_addrcheck.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,8 +16,8 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: Checks the memory map for the address // Comments: // @@ -34,21 +34,21 @@ module lsu_addrcheck input lsu_pkt_t lsu_pkt_dc1, // packet in dc1 input logic [31:0] dec_tlu_mrac_ff, // CSR read - + output logic is_sideeffects_dc2, // is sideffects space - output logic is_sideeffects_dc3, + output logic is_sideeffects_dc3, output logic addr_in_dccm_dc1, // address in dccm output logic addr_in_pic_dc1, // address in pic output logic addr_external_dc1, // address in external output logic access_fault_dc1, // access fault - output logic misaligned_fault_dc1, // misaligned - - input logic scan_mode + output logic misaligned_fault_dc1, // misaligned + + input logic scan_mode ); - + `include "global.h" - + localparam DCCM_REGION = `RV_DCCM_REGION; localparam PIC_REGION = `RV_PIC_REGION; localparam ICCM_REGION = `RV_ICCM_REGION; @@ -58,13 +58,13 @@ module lsu_addrcheck `else localparam ICCM_ENABLE = 1'b0; `endif - + `ifdef RV_DCCM_ENABLE localparam DCCM_ENABLE = 1'b1; `else localparam DCCM_ENABLE = 1'b0; `endif - + logic is_sideeffects_dc1, is_aligned_dc1; logic start_addr_in_dccm_dc1, end_addr_in_dccm_dc1; logic start_addr_in_dccm_region_dc1, end_addr_in_dccm_region_dc1; @@ -72,7 +72,7 @@ module lsu_addrcheck logic start_addr_in_pic_region_dc1, end_addr_in_pic_region_dc1; logic [4:0] csr_idx; logic addr_in_iccm; - + if (DCCM_ENABLE == 1) begin: Gen_dccm_enable // Start address check rvrangecheck #(.CCM_SADR(`RV_DCCM_SADR), @@ -81,7 +81,7 @@ module lsu_addrcheck .in_range(start_addr_in_dccm_dc1), .in_region(start_addr_in_dccm_region_dc1) ); - + // End address check rvrangecheck #(.CCM_SADR(`RV_DCCM_SADR), .CCM_SIZE(`RV_DCCM_SIZE)) end_addr_dccm_rangecheck ( @@ -97,10 +97,10 @@ module lsu_addrcheck end if (ICCM_ENABLE == 1) begin : check_iccm assign addr_in_iccm = (start_addr_dc1[31:28] == ICCM_REGION); - end + end else begin assign addr_in_iccm = 1'b0; - end + end // PIC memory check // Start address check rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR), @@ -109,7 +109,7 @@ module lsu_addrcheck .in_range(start_addr_in_pic_dc1), .in_region(start_addr_in_pic_region_dc1) ); - + // End address check rvrangecheck #(.CCM_SADR(`RV_PIC_BASE_ADDR), .CCM_SIZE(`RV_PIC_SIZE)) end_addr_pic_rangecheck ( @@ -118,12 +118,12 @@ module lsu_addrcheck .in_region(end_addr_in_pic_region_dc1) ); - assign addr_in_dccm_dc1 = (start_addr_in_dccm_dc1 & end_addr_in_dccm_dc1); - assign addr_in_pic_dc1 = (start_addr_in_pic_dc1 & end_addr_in_pic_dc1); - - assign addr_external_dc1 = ~(addr_in_dccm_dc1 | addr_in_pic_dc1); //~addr_in_dccm_region_dc1; + assign addr_in_dccm_dc1 = (start_addr_in_dccm_dc1 & end_addr_in_dccm_dc1); + assign addr_in_pic_dc1 = (start_addr_in_pic_dc1 & end_addr_in_pic_dc1); + + assign addr_external_dc1 = ~(addr_in_dccm_dc1 | addr_in_pic_dc1); //~addr_in_dccm_region_dc1; assign csr_idx[4:0] = {start_addr_dc1[31:28], 1'b1}; - assign is_sideeffects_dc1 = dec_tlu_mrac_ff[csr_idx] & ~(start_addr_in_dccm_region_dc1 | start_addr_in_pic_region_dc1 | addr_in_iccm); //every region has the 2 LSB indicating ( 1: sideeffects/no_side effects, and 0: cacheable ). Ignored in internal regions + assign is_sideeffects_dc1 = dec_tlu_mrac_ff[csr_idx] & ~(start_addr_in_dccm_region_dc1 | start_addr_in_pic_region_dc1 | addr_in_iccm); //every region has the 2 LSB indicating ( 1: sideeffects/no_side effects, and 0: cacheable ). Ignored in internal regions assign is_aligned_dc1 = (lsu_pkt_dc1.word & (start_addr_dc1[1:0] == 2'b0)) | (lsu_pkt_dc1.half & (start_addr_dc1[0] == 1'b0)) | lsu_pkt_dc1.by; @@ -135,25 +135,25 @@ module lsu_addrcheck // 3. Ld/St access to picm are not word aligned // 4. Uncorrectable (double bit) ECC error if (DCCM_REGION == PIC_REGION) begin - assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~(start_addr_in_dccm_dc1 | start_addr_in_pic_dc1)) | + assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~(start_addr_in_dccm_dc1 | start_addr_in_pic_dc1)) | (end_addr_in_dccm_region_dc1 & ~(end_addr_in_dccm_dc1 | end_addr_in_pic_dc1)) | ((start_addr_dc1[27:18] != end_addr_dc1[27:18]) & start_addr_in_dccm_dc1) | (addr_in_pic_dc1 & (start_addr_dc1[1:0] != 2'b0))) & lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma; end else begin - assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~start_addr_in_dccm_dc1) | + assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~start_addr_in_dccm_dc1) | (end_addr_in_dccm_region_dc1 & ~end_addr_in_dccm_dc1) | - (start_addr_in_pic_region_dc1 & ~start_addr_in_pic_dc1) | + (start_addr_in_pic_region_dc1 & ~start_addr_in_pic_dc1) | (end_addr_in_pic_region_dc1 & ~end_addr_in_pic_dc1) | (addr_in_pic_dc1 & (start_addr_dc1[1:0] != 2'b0))) & lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma; end - + // Misaligned happens due to 2 reasons // 1. Region cross // 2. sideeffects access which are not aligned - assign misaligned_fault_dc1 = ((start_addr_dc1[31:28] != end_addr_dc1[31:28]) | + assign misaligned_fault_dc1 = ((start_addr_dc1[31:28] != end_addr_dc1[31:28]) | (is_sideeffects_dc1 & ~is_aligned_dc1)) & addr_external_dc1 & lsu_pkt_dc1.valid & ~lsu_pkt_dc1.dma; rvdff #(.WIDTH(1)) is_sideeffects_dc2ff (.din(is_sideeffects_dc1), .dout(is_sideeffects_dc2), .clk(lsu_freeze_c2_dc2_clk), .*); rvdff #(.WIDTH(1)) is_sideeffects_dc3ff (.din(is_sideeffects_dc2), .dout(is_sideeffects_dc3), .clk(lsu_freeze_c2_dc3_clk), .*); - + endmodule // lsu_addrcheck diff --git a/design/lsu/lsu_bus_intf.sv b/design/lsu/lsu_bus_intf.sv index 6affff9..6b4d7a6 100644 --- a/design/lsu/lsu_bus_intf.sv +++ b/design/lsu/lsu_bus_intf.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,8 +16,8 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: lsu interface with interface queue // Comments: // @@ -31,9 +31,9 @@ module lsu_bus_intf input logic dec_tlu_non_blocking_disable, // disable non block input logic dec_tlu_wb_coalescing_disable, // disable write buffer coalescing input logic dec_tlu_ld_miss_byp_wb_disable, // disable ld miss bypass of the write buffer - + // various clocks needed for the bus reads and writes - input logic lsu_c1_dc3_clk, + input logic lsu_c1_dc3_clk, input logic lsu_c1_dc4_clk, input logic lsu_c1_dc5_clk, input logic lsu_c2_dc3_clk, @@ -47,9 +47,9 @@ module lsu_bus_intf input logic lsu_wrbuf_c1_clk, input logic lsu_free_c2_clk, input logic lsu_busm_clk, - + input logic lsu_busreq_dc2, // bus request is in dc2 - + input lsu_pkt_t lsu_pkt_dc1, // lsu packet flowing down the pipe input lsu_pkt_t lsu_pkt_dc2, // lsu packet flowing down the pipe input lsu_pkt_t lsu_pkt_dc3, // lsu packet flowing down the pipe @@ -68,7 +68,7 @@ module lsu_bus_intf input logic [31:0] end_addr_dc4, // lsu address flowing down the pipe input logic [31:0] end_addr_dc5, // lsu address flowing down the pipe - input logic addr_external_dc2, // lsu instruction going to external + input logic addr_external_dc2, // lsu instruction going to external input logic addr_external_dc3, // lsu instruction going to external input logic addr_external_dc4, // lsu instruction going to external input logic addr_external_dc5, // lsu instruction going to external @@ -81,7 +81,7 @@ module lsu_bus_intf input logic lsu_commit_dc5, // lsu instruction in dc5 commits input logic is_sideeffects_dc2, // lsu attribute is side_effects input logic is_sideeffects_dc3, // lsu attribute is side_effects - input logic flush_dc2_up, // flush + input logic flush_dc2_up, // flush input logic flush_dc3, // flush input logic flush_dc4, // flush input logic flush_dc5, // flush @@ -96,7 +96,7 @@ module lsu_bus_intf output logic [31:0] bus_read_data_dc3, // the Dc3 load data output logic ld_bus_error_dc3, // bus error in dc3 - output logic [31:0] ld_bus_error_addr_dc3, // address of the bus error + output logic [31:0] ld_bus_error_addr_dc3, // address of the bus error output logic lsu_imprecise_error_load_any, // imprecise load bus error output logic lsu_imprecise_error_store_any, // imprecise store bus error @@ -108,18 +108,18 @@ module lsu_bus_intf output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // the tag of the external non block load output logic lsu_nonblock_load_inv_dc5, // invalidate signal for the cam entry for non block loads output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // tag of the enrty which needs to be invalidated - output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam - output logic lsu_nonblock_load_data_error, // non block load has an error - output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error - output logic [31:0] lsu_nonblock_load_data, // Data of the non block load + output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam + output logic lsu_nonblock_load_data_error, // non block load has an error + output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error + output logic [31:0] lsu_nonblock_load_data, // Data of the non block load // PMU events output logic lsu_pmu_bus_trxn, output logic lsu_pmu_bus_misaligned, output logic lsu_pmu_bus_error, output logic lsu_pmu_bus_busy, - - // AXI signals + + // AXI signals // AXI Write Channels output logic lsu_axi_awvalid, input logic lsu_axi_awready, @@ -133,8 +133,8 @@ module lsu_bus_intf output logic [3:0] lsu_axi_awcache, output logic [2:0] lsu_axi_awprot, output logic [3:0] lsu_axi_awqos, - - output logic lsu_axi_wvalid, + + output logic lsu_axi_wvalid, input logic lsu_axi_wready, output logic [63:0] lsu_axi_wdata, output logic [7:0] lsu_axi_wstrb, @@ -165,7 +165,7 @@ module lsu_bus_intf input logic [63:0] lsu_axi_rdata, input logic [1:0] lsu_axi_rresp, input logic lsu_axi_rlast, - + input logic lsu_bus_clk_en ); @@ -173,26 +173,26 @@ module lsu_bus_intf `include "global.h" logic rdbuf_full_freeze_dc3; - logic ld_freeze_dc3; + logic ld_freeze_dc3; - logic store_freeze_dc3; + logic store_freeze_dc3; logic lsu_bus_clk_en_q; logic write_buffer_block_any; // Block the write buffer if there are outstanding non-blocking loads logic ldst_dual_dc1, ldst_dual_dc2, ldst_dual_dc3, ldst_dual_dc4, ldst_dual_dc5; logic lsu_read_buffer_block_dc2; - + logic [3:0] ldst_byteen_dc2, ldst_byteen_dc3, ldst_byteen_dc4, ldst_byteen_dc5; logic [15:0] ldst_byteen_ext_dc2, ldst_byteen_ext_dc3, ldst_byteen_ext_dc4, ldst_byteen_ext_dc5; logic [7:0] ldst_byteen_hi_dc2, ldst_byteen_hi_dc3, ldst_byteen_hi_dc4, ldst_byteen_hi_dc5; logic [7:0] ldst_byteen_lo_dc2, ldst_byteen_lo_dc3, ldst_byteen_lo_dc4, ldst_byteen_lo_dc5; logic is_sideeffects_dc4, is_sideeffects_dc5; - + logic [127:0] store_data_ext_dc3, store_data_ext_dc4, store_data_ext_dc5; logic [63:0] store_data_hi_dc3, store_data_hi_dc4, store_data_hi_dc5; logic [63:0] store_data_lo_dc3, store_data_lo_dc4, store_data_lo_dc5; - + logic ld_addr_dc3hit_lo_lo, ld_addr_dc3hit_hi_lo, ld_addr_dc3hit_lo_hi, ld_addr_dc3hit_hi_hi; logic ld_addr_dc4hit_lo_lo, ld_addr_dc4hit_hi_lo, ld_addr_dc4hit_lo_hi, ld_addr_dc4hit_hi_hi; logic ld_addr_dc5hit_lo_lo, ld_addr_dc5hit_hi_lo, ld_addr_dc5hit_lo_hi, ld_addr_dc5hit_hi_hi; @@ -209,14 +209,14 @@ module lsu_bus_intf logic [7:0] ld_byte_hit_wrbuf_lo, ld_byte_hit_wrbuf_hi; logic [63:0] ld_fwddata_wrbuf_lo, ld_fwddata_wrbuf_hi; - + logic ld_hit_rdbuf_hi, ld_hit_rdbuf_lo; logic [63:0] ld_fwddata_rdbuf_hi, ld_fwddata_rdbuf_lo; logic [63:0] ld_fwddata_lo, ld_fwddata_hi; logic [31:0] ld_fwddata_dc2, ld_fwddata_dc3; logic [31:0] ld_read_buffer_data_dc3; - + logic ld_full_hit_hi_dc2, ld_full_hit_lo_dc2; logic ld_hit_dc2, ld_full_hit_dc2, ld_full_hit_dc3; logic is_aligned_dc5; @@ -226,7 +226,7 @@ module lsu_bus_intf logic ld_imprecise_bus_error_any; logic [31:0] ld_imprecise_bus_error_addr; logic [127:32] ld_fwddata_dc2_nc; - + // PMU signals assign lsu_pmu_bus_trxn = (lsu_axi_awvalid & lsu_axi_awready) | (lsu_axi_arvalid & lsu_axi_arready); assign lsu_pmu_bus_misaligned = lsu_busreq_dc2 & ldst_dual_dc2; @@ -238,12 +238,12 @@ module lsu_bus_intf ({4{lsu_pkt_dc2.word}} & 4'b1111); assign ldst_dual_dc1 = (lsu_addr_dc1[3] != end_addr_dc1[3]); assign lsu_freeze_dc3 = (rdbuf_full_freeze_dc3 | ld_freeze_dc3 | store_freeze_dc3) & ~(flush_dc4 | flush_dc5); - + assign lsu_imprecise_error_load_any = ld_imprecise_bus_error_any; assign lsu_imprecise_error_store_any = store_bus_error_any & ~ld_imprecise_bus_error_any; assign lsu_imprecise_error_addr_any[31:0] = ld_imprecise_bus_error_any ? ld_imprecise_bus_error_addr[31:0] : store_bus_error_addr[31:0]; //assign ld_bus_error_addr_dc3[31:0] = last_bus_addr[31:0]; - + // Determine if the packet is word aligned assign is_aligned_dc5 = (lsu_pkt_dc5.word & (lsu_addr_dc5[1:0] == 2'b0)) | (lsu_pkt_dc5.half & (lsu_addr_dc5[0] == 1'b0)); @@ -257,7 +257,7 @@ module lsu_bus_intf lsu_bus_write_buffer bus_write_buffer ( .* ); - + // Create Hi/Lo signals assign ldst_byteen_ext_dc2[15:0] = {12'b0,ldst_byteen_dc2[3:0]} << lsu_addr_dc2[2:0]; assign ldst_byteen_ext_dc3[15:0] = {12'b0,ldst_byteen_dc3[3:0]} << lsu_addr_dc3[2:0]; @@ -267,7 +267,7 @@ module lsu_bus_intf assign store_data_ext_dc3[127:0] = {64'b0,store_data_dc3[63:0]} << {lsu_addr_dc3[2:0],3'b0}; assign store_data_ext_dc4[127:0] = {96'b0,store_data_dc4[31:0]} << {lsu_addr_dc4[2:0],3'b0}; assign store_data_ext_dc5[127:0] = {96'b0,store_data_dc5[31:0]} << {lsu_addr_dc5[2:0],3'b0}; - + assign ldst_byteen_hi_dc2[7:0] = ldst_byteen_ext_dc2[15:8]; assign ldst_byteen_lo_dc2[7:0] = ldst_byteen_ext_dc2[7:0]; assign ldst_byteen_hi_dc3[7:0] = ldst_byteen_ext_dc3[15:8]; @@ -283,7 +283,7 @@ module lsu_bus_intf assign store_data_lo_dc4[63:0] = store_data_ext_dc4[63:0]; assign store_data_hi_dc5[63:0] = store_data_ext_dc5[127:64]; assign store_data_lo_dc5[63:0] = store_data_ext_dc5[63:0]; - + assign ld_addr_dc3hit_lo_lo = (lsu_addr_dc2[31:3] == lsu_addr_dc3[31:3]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2; assign ld_addr_dc3hit_lo_hi = (end_addr_dc2[31:3] == lsu_addr_dc3[31:3]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2; assign ld_addr_dc3hit_hi_lo = (lsu_addr_dc2[31:3] == end_addr_dc3[31:3]) & lsu_pkt_dc3.valid & lsu_pkt_dc3.store & lsu_busreq_dc2; @@ -354,7 +354,7 @@ module lsu_bus_intf ld_byte_dc5hit_lo[i] ? ld_fwddata_dc5pipe_lo[(8*i)+7:(8*i)] : ld_byte_hit_wrbuf_lo[i] ? ld_fwddata_wrbuf_lo[(8*i)+7:(8*i)] : ld_fwddata_rdbuf_lo[(8*i)+7:(8*i)]; - + assign ld_fwddata_hi[(8*i)+7:(8*i)] = ld_byte_dc3hit_hi[i] ? ld_fwddata_dc3pipe_hi[(8*i)+7:(8*i)] : ld_byte_dc4hit_hi[i] ? ld_fwddata_dc4pipe_hi[(8*i)+7:(8*i)] : ld_byte_dc5hit_hi[i] ? ld_fwddata_dc5pipe_hi[(8*i)+7:(8*i)] : @@ -363,7 +363,7 @@ module lsu_bus_intf end - always_comb begin + always_comb begin ld_full_hit_lo_dc2 = 1'b1; ld_full_hit_hi_dc2 = 1'b1; for (int i=0; i<8; i++) begin @@ -384,7 +384,7 @@ module lsu_bus_intf assign {ld_fwddata_dc2_nc[127:32], ld_fwddata_dc2[31:0]} = {ld_fwddata_hi[63:0], ld_fwddata_lo[63:0]} >> (8*lsu_addr_dc2[2:0]); assign bus_read_data_dc3[31:0] = ld_full_hit_dc3 ? ld_fwddata_dc3[31:0] : ld_read_buffer_data_dc3[31:0]; - + // Fifo flops rvdff #(.WIDTH(1)) lsu_full_hit_dc3ff (.din(ld_full_hit_dc2), .dout(ld_full_hit_dc3), .clk(lsu_freeze_c2_dc3_clk), .*); rvdff #(.WIDTH(32)) lsu_fwddata_dc3ff (.din(ld_fwddata_dc2[31:0]), .dout(ld_fwddata_dc3[31:0]), .clk(lsu_c1_dc3_clk), .*); @@ -401,7 +401,7 @@ module lsu_bus_intf rvdff #(4) lsu_byten_dc3ff (.*, .din(ldst_byteen_dc2[3:0]), .dout(ldst_byteen_dc3[3:0]), .clk(lsu_freeze_c1_dc3_clk)); rvdff #(4) lsu_byten_dc4ff (.*, .din(ldst_byteen_dc3[3:0]), .dout(ldst_byteen_dc4[3:0]), .clk(lsu_c1_dc4_clk)); rvdff #(4) lsu_byten_dc5ff (.*, .din(ldst_byteen_dc4[3:0]), .dout(ldst_byteen_dc5[3:0]), .clk(lsu_c1_dc5_clk)); - + `ifdef ASSERT_ON // Assertion to check ld imprecise error comes with right address property lsu_ld_imprecise_error_check; @@ -424,9 +424,9 @@ module lsu_bus_intf ((lsu_axi_awsize[2:0] == 3'h2) & (lsu_axi_awaddr[1:0] == 2'b0)) | ((lsu_axi_awsize[2:0] == 3'h3) & (lsu_axi_awaddr[2:0] == 3'b0))); endproperty - assert_lsu_write_trxn_aligned: assert property (lsu_axi_write_trxn_aligned) else + assert_lsu_write_trxn_aligned: assert property (lsu_axi_write_trxn_aligned) else $display("Assertion lsu_axi_write_trxn_aligned failed: lsu_axi_awvalid=1'b%b, lsu_axi_awsize=3'h%h, lsu_axi_awaddr=32'h%h",lsu_axi_awvalid, lsu_axi_awsize[2:0], lsu_axi_awaddr[31:0]); - + // Assertion to check AXI read address is aligned to size property lsu_axi_read_trxn_aligned; @(posedge lsu_busm_clk) disable iff(~rst_l) lsu_axi_arvalid |-> ((lsu_axi_arsize[2:0] == 3'h0) | @@ -434,9 +434,9 @@ module lsu_bus_intf ((lsu_axi_arsize[2:0] == 3'h2) & (lsu_axi_araddr[1:0] == 2'b0)) | ((lsu_axi_arsize[2:0] == 3'h3) & (lsu_axi_araddr[2:0] == 3'b0))); endproperty - assert_lsu_read_trxn_aligned: assert property (lsu_axi_read_trxn_aligned) else + assert_lsu_read_trxn_aligned: assert property (lsu_axi_read_trxn_aligned) else $display("Assertion lsu_axi_read_trxn_aligned failed: lsu_axi_arvalid=1'b%b, lsu_axi_arsize=3'h%h, lsu_axi_araddr=32'h%h",lsu_axi_arvalid, lsu_axi_arsize[2:0], lsu_axi_araddr[31:0]); - + // Assertion to check cmd valid stays stable during entire bus clock property lsu_axi_awvalid_stable; @(posedge clk) disable iff(~rst_l) (lsu_axi_awvalid != $past(lsu_axi_awvalid)) |-> $past(lsu_bus_clk_en); diff --git a/design/lsu/lsu_bus_read_buffer.sv b/design/lsu/lsu_bus_read_buffer.sv index 33a0af0..bc63705 100644 --- a/design/lsu/lsu_bus_read_buffer.sv +++ b/design/lsu/lsu_bus_read_buffer.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,9 +15,9 @@ //******************************************************************************** // $Id$ -// -// -// Owner: +// +// +// Owner: // Function: lsu to bus interface with interface queue // Comments: // @@ -33,17 +33,17 @@ function automatic logic [31:0] lsu_align; logic [95:0] data_int; logic [31:0] data_out; logic [2:0] shift; - + shift[2:0] = data_sel ? {1'b0,addr[1:0]} : addr[2:0]; // This is need since we already save either upper/lower word for dual data_int[95:0] = (data_sel ? {data1[63:0], data0[31:0]} : {data0[31:0], data1[63:0]}) >> 8*shift[2:0]; - + data_out[31:0] = ({32{ unsign & (size == 2'b00)}} & {24'b0,data_int[7:0]}) | ({32{ unsign & (size == 2'b01)}} & {16'b0,data_int[15:0]}) | ({32{~unsign & (size == 2'b00)}} & {{24{data_int[7]}}, data_int[7:0]}) | ({32{~unsign & (size == 2'b01)}} & {{16{data_int[15]}},data_int[15:0]}) | ({32{(size == 2'b10)}} & data_int[31:0]); - return data_out[31:0]; - + return data_out[31:0]; + endfunction // lsu_bus_read_buffer @@ -52,12 +52,12 @@ module lsu_bus_read_buffer ( input logic lsu_freeze_c2_dc3_clk, - input logic lsu_c2_dc3_clk, // per stage clock - input logic lsu_c2_dc4_clk, // per stage clock - input logic lsu_c2_dc5_clk, // per stage clock - input logic lsu_rdbuf_c1_clk, // read_buf clock - input logic lsu_free_c2_clk, // lsu clock - input logic lsu_busm_clk, // bus clock + input logic lsu_c2_dc3_clk, // per stage clock + input logic lsu_c2_dc4_clk, // per stage clock + input logic lsu_c2_dc5_clk, // per stage clock + input logic lsu_rdbuf_c1_clk, // read_buf clock + input logic lsu_free_c2_clk, // lsu clock + input logic lsu_busm_clk, // bus clock input logic clk, // core clock input logic rst_l, // reset @@ -68,20 +68,20 @@ module lsu_bus_read_buffer input logic ldst_dual_dc2, // packet in dc2 is unaligned input logic ldst_dual_dc3, // packet in dc3 is unaligned input logic [31:0] lsu_addr_dc2, // address - input logic [31:0] end_addr_dc2, // ending address ( to calculate the banks ) + input logic [31:0] end_addr_dc2, // ending address ( to calculate the banks ) input logic [31:0] lsu_addr_dc3, // start address in dc5 input logic [31:0] end_addr_dc3, // end address in dc5 input logic addr_external_dc2, // the address is mapping to external input logic lsu_read_buffer_block_dc2, // block the read buffer - either because of a partial hit, or chicken bit set input logic is_sideeffects_dc2, - + input logic lsu_freeze_dc3, // Final lsu freeze input logic lsu_commit_dc5, // Final qualified commit input logic lsu_write_buffer_empty_any, // write buffer is empty input logic ld_full_hit_dc2, // load can get all its byte from a write buffer entry input logic is_sideeffects_dc3, - input logic flush_dc2_up, // flush - input logic flush_dc3, // flush + input logic flush_dc2_up, // flush + input logic flush_dc3, // flush input logic flush_dc4, // flush input logic flush_dc5, // flush @@ -91,13 +91,13 @@ module lsu_bus_read_buffer output logic lsu_ldbusreq_dc5, // pipe made it down to dc5 and is to external output logic ld_hit_rdbuf_hi, // load is unaligned and the upper hits output logic ld_hit_rdbuf_lo, // load us unaligned and the lower hits - output logic [63:0] ld_fwddata_rdbuf_hi, // the fwd data + output logic [63:0] ld_fwddata_rdbuf_hi, // the fwd data output logic [63:0] ld_fwddata_rdbuf_lo, // the fwd data output logic ld_freeze_dc3, // need to freeze as the load is to the external output logic rdbuf_full_freeze_dc3, // Freeze in dc2 since read buffer is full - output logic ld_bus_error_dc3, // Bus returns an precise error + output logic ld_bus_error_dc3, // Bus returns an precise error output logic [31:0] ld_bus_error_addr_dc3, // Address for precise load error - output logic ld_imprecise_bus_error_any, // Bus returns an imprecise error + output logic ld_imprecise_bus_error_any, // Bus returns an imprecise error output logic [31:0] ld_imprecise_bus_error_addr, output logic [31:0] ld_read_buffer_data_dc3, // the bus return data @@ -108,10 +108,10 @@ module lsu_bus_read_buffer output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_tag_dc3, // the tag of the external non block load output logic lsu_nonblock_load_inv_dc5, // invalidate signal for the cam entry for non block loads output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_inv_tag_dc5, // tag of the enrty which needs to be invalidated - output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam - output logic lsu_nonblock_load_data_error, // non block load has an error - output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error - output logic [31:0] lsu_nonblock_load_data, // Data of the non block load + output logic lsu_nonblock_load_data_valid, // the non block is valid - sending information back to the cam + output logic lsu_nonblock_load_data_error, // non block load has an error + output logic [`RV_LSU_NUM_NBLOAD_WIDTH-1:0] lsu_nonblock_load_data_tag, // the tag of the non block load sending the data/error + output logic [31:0] lsu_nonblock_load_data, // Data of the non block load // AXI Read Channels output logic lsu_axi_arvalid, @@ -133,9 +133,9 @@ module lsu_bus_read_buffer input logic [63:0] lsu_axi_rdata, input logic [1:0] lsu_axi_rresp, input logic lsu_axi_rlast, - - input logic lsu_bus_clk_en, - input logic lsu_bus_clk_en_q, + + input logic lsu_bus_clk_en, + input logic lsu_bus_clk_en_q, input logic scan_mode // scan mode ); @@ -145,7 +145,7 @@ module lsu_bus_read_buffer // States for entries // For Ld: IDLE -> WAIT_COMMIT -> WAIT -> CMD -> RESP -> DONE -> IDLE typedef enum logic [2:0] {IDLE=3'b000, WAIT_COMMIT=3'b001, WAIT=3'b010, CMD=3'b011, RESP=3'b100, DONE=3'b101} state_t; - + localparam DEPTH = `RV_LSU_NUM_NBLOAD; localparam DEPTH_LOG2 = `RV_LSU_NUM_NBLOAD_WIDTH; @@ -181,20 +181,20 @@ module lsu_bus_read_buffer logic [31:0] busfifo_addr_lo_in; logic [31:0] busfifo_addr_hi_in; logic [1:0] busfifo_sz_in; - + logic lsu_ldbusreq_dc2, lsu_ldbusreq_dc4; logic WrPtrEn; logic [DEPTH_LOG2-1:0] WrPtr, NxtWrPtr, WrPtr_dc3, WrPtr_dc4, WrPtr_dc5; logic [DEPTH_LOG2-1:0] CmdPtr, NxtCmdPtr, CmdPtrQ; logic [DEPTH_LOG2-1:0] FreezePtr; - logic FreezePtrEn; + logic FreezePtrEn; logic lsu_nonblock_load_valid_dc4, lsu_nonblock_load_valid_dc5; logic ld_freeze_en, ld_freeze_rst; logic rdbuf_full_freeze_en, rdbuf_full_freeze_rst; logic ld_precise_bus_error; logic read_buffer_full; - + logic [127:32] ld_read_buffer_data_dc3_nc; logic found0, found1; @@ -202,7 +202,7 @@ module lsu_bus_read_buffer logic dec_nonblock_load_freeze_dc3; logic lsu_read_buffer_block_dc3; //assign dec_nonblock_load_freeze_dc2 = '0; - + logic lsu_axi_arvalid_q, lsu_axi_arready_q; logic lsu_axi_rvalid_q, lsu_axi_rready_q; logic [1:0] lsu_axi_rresp_q; @@ -212,9 +212,9 @@ module lsu_bus_read_buffer logic disable_nonblock_load; //logic lsu_wb_empty_any; logic store_hit_rdbuf_dc2; - + assign disable_nonblock_load = dec_tlu_non_blocking_disable; - + //assign busfifo_addr_in[0] = lsu_addr_dc5[31:0]; //assign busfifo_addr_in[1] = end_addr_dc5[31:0]; always_comb begin @@ -227,7 +227,7 @@ module lsu_bus_read_buffer end end end - + assign WrPtrEn = (lsu_ldbusreq_dc3 & lsu_pkt_dc3.valid & lsu_pkt_dc3.load & ~rdbuf_full_freeze_dc3) | (|busfifo_rst[DEPTH-1:0]); always_comb begin NxtWrPtr = WrPtr; @@ -246,10 +246,10 @@ module lsu_bus_read_buffer read_buffer_full &= ((busfifo_state[i] != IDLE) | ((busfifo_state[i] == IDLE) & lsu_ldbusreq_dc3 & ~rdbuf_full_freeze_dc3 & (DEPTH_LOG2'(i) == WrPtr)));// (busfifo_state_en[i])); end end - + //assign CmdPtr = (busfifo_state[CmdPtrQ] != CMD) ? NxtCmdPtr : CmdPtrQ; assign CmdPtr = (((busfifo_state[CmdPtrQ] == CMD) & busfifo_state_bus_en[CmdPtrQ]) | (busfifo_state[CmdPtrQ] != CMD)) ? NxtCmdPtr : CmdPtrQ; - + // Don't drive b2b reads for the time being (This is done to keep the signals constant over the entire bus clock) //assign lsu_axi_arvalid = (busfifo_state[CmdPtr] == CMD) & (~busfifo_block[CmdPtr] | lsu_wb_empty_any) & ~(lsu_axi_arvalid_q & lsu_axi_arready_q); //assign lsu_axi_arvalid = (busfifo_state[CmdPtr] == CMD) & ~busfifo_block[CmdPtr] & ~(lsu_axi_arvalid_q & lsu_axi_arready_q); @@ -259,19 +259,19 @@ module lsu_bus_read_buffer (busfifo_sent[CmdPtr][0] | busfifo_sent_en[CmdPtr][0]) ? {busfifo_addr_hi[CmdPtr][31:3],3'b0} : {busfifo_addr_lo[CmdPtr][31:3],3'b0}; assign lsu_axi_arsize[2:0] = busfifo_sideeffects[CmdPtr] ? {1'b0,busfifo_sz[CmdPtr][1:0]} : 3'b011; assign lsu_axi_arcache[3:0] = busfifo_sideeffects[CmdPtr] ? 4'b0 : 4'b1111; - assign lsu_axi_arprot[2:0] = 3'b0; + assign lsu_axi_arprot[2:0] = 3'b0; assign lsu_axi_arregion[3:0] = lsu_axi_araddr[31:28]; assign lsu_axi_arlen[7:0] = '0; assign lsu_axi_arburst[1:0] = 2'b01; assign lsu_axi_arqos[3:0] = '0; assign lsu_axi_arlock = '0; - + assign lsu_axi_rready = 1'b1; assign busfifo_addr_lo_in = lsu_addr_dc3[31:0]; assign busfifo_addr_hi_in = end_addr_dc3[31:0]; assign busfifo_sz_in = {lsu_pkt_dc3.word, lsu_pkt_dc3.half}; - + for (genvar i=0; i WAIT -> CMD -> RESP -> IDLE typedef enum logic [2:0] {IDLE=3'b000, WAIT=3'b001, CMD=3'b010, CMD_ADDR=3'b011, CMD_DATA=3'b100, RESP=3'b101} state_t; @@ -156,7 +156,7 @@ module lsu_bus_write_buffer localparam DEPTH = LSU_WRBUF_DEPTH; localparam DEPTH_LOG2 = $clog2(DEPTH); localparam WATERMARK = 0; // Not tested for anything other than 0 (will need fence to drain write buffer if it's non zero) - + state_t [DEPTH-1:0] busfifo_state; state_t [DEPTH-1:0] busfifo_nxtstate; logic [DEPTH-1:0] busfifo_state_en; @@ -169,23 +169,23 @@ module lsu_bus_write_buffer logic [DEPTH-1:0][7:0] busfifo_byteen; logic [DEPTH-1:0][1:0] busfifo_size; logic [DEPTH-1:0] busfifo_sideeffects; - + logic [DEPTH-1:0][7:0] busfifo_byteen_in; logic [DEPTH-1:0][1:0] busfifo_size_in; logic [DEPTH-1:0][63:0] busfifo_data_in; logic [DEPTH-1:0][31:0] busfifo_addr_in; logic [DEPTH-1:0][31:0] busfifo_addr_in_temp; //logic [DEPTH-1:0] store_bus_error_vec; - + logic [DEPTH-1:0] store_hitvec_hi_dc5, store_hitvec_lo_dc5; logic store_merge_hi_dc5, store_merge_lo_dc5, store_merge_all_dc5; logic store_busreq_hi_dc5, store_busreq_lo_dc5; - + logic [127:0] store_data_ext_dc5; logic [63:0] store_data_hi_dc5, store_data_lo_dc5; logic [7:0] ldst_byteen_hi_dc5, ldst_byteen_lo_dc5; logic [7:0] ldst_byteen_mask_lo_dc5; - + logic [7:0] ldst_byteen_hi_dc2, ldst_byteen_lo_dc2; logic [DEPTH-1:0] ld_addr_hitvec_lo, ld_addr_hitvec_hi; logic [DEPTH-1:0][7:0] ld_byte_hitvec_lo, ld_byte_hitvec_hi; @@ -204,7 +204,7 @@ module lsu_bus_write_buffer logic [3:0] wrbuf_numvld_any, wrbuf_numvld_anyQ; logic [3:0] wrbuf_specvld_any; logic [1:0] wrbuf_specvld_dc1, wrbuf_specvld_dc2, wrbuf_specvld_dc3, wrbuf_specvld_dc4, wrbuf_specvld_dc5; - + logic store_freeze_en, store_freeze_rst; logic lsu_axi_awvalid_q, lsu_axi_awready_q; @@ -215,7 +215,7 @@ module lsu_bus_write_buffer logic [1:0] store_bus_error_lo; logic [1:0] store_bus_error_lw; logic [1:0] store_bus_error_uw; - + //assign store_data_ext_dc5[127:0] = {96'b0, store_data_dc5[31:0]} << {8*lsu_addr_dc5[2:0]}; assign store_data_ext_dc5[127:0] = {96'b0, store_data_dc5[31:0]} << {lsu_addr_dc5[2:0],3'b0}; @@ -226,7 +226,7 @@ module lsu_bus_write_buffer assign ldst_byteen_mask_lo_dc5[7:0] = 8'hff << lsu_addr_dc5[2:0]; - + // Hit logic for coalescing assign store_merge_hi_dc5 = 1'b0; //|store_hitvec_hi_dc5[DEPTH-1:0]; @@ -241,7 +241,7 @@ module lsu_bus_write_buffer assign store_hitvec_lo_dc5[i] = (lsu_addr_dc5[31:3] == busfifo_addr[i][31:3]) & ~(|(busfifo_byteen[i][7:0] & ldst_byteen_mask_lo_dc5[7:0])) & ~dec_tlu_wb_coalescing_disable & ~is_sideeffects_dc5 & ((busfifo_state[i] == WAIT)| (busfifo_state[i] == CMD)) & (i != CmdPtr[DEPTH_LOG2-1:0]) & (i != CmdPtrQ[DEPTH_LOG2-1:0]) & lsu_stbusreq_dc5 & lsu_commit_dc5; end - + // Generate the busfifo inputs always_comb begin for (int i=0; idc5 even if there is a freeze assign lsu_c1_dc1_clken = lsu_p.valid | dma_dccm_req | clk_override; assign lsu_c1_dc2_clken = lsu_pkt_dc1.valid | lsu_c1_dc1_clken_q | clk_override; @@ -139,12 +139,12 @@ module lsu_clkdomain assign lsu_freeze_c1_dc2_clken = (lsu_pkt_dc1.valid | clk_override) & ~lsu_freeze_dc3; assign lsu_freeze_c1_dc3_clken = (lsu_pkt_dc2.valid | clk_override) & ~lsu_freeze_dc3; assign lsu_freeze_c1_dc4_clken = (lsu_pkt_dc3.valid | clk_override) & ~lsu_freeze_dc3; - + assign lsu_freeze_c2_dc1_clken = (lsu_freeze_c1_dc1_clken | lsu_freeze_c1_dc1_clken_q | clk_override) & ~lsu_freeze_dc3; assign lsu_freeze_c2_dc2_clken = (lsu_freeze_c1_dc2_clken | lsu_freeze_c1_dc2_clken_q | clk_override) & ~lsu_freeze_dc3; assign lsu_freeze_c2_dc3_clken = (lsu_freeze_c1_dc3_clken | lsu_freeze_c1_dc3_clken_q | clk_override) & ~lsu_freeze_dc3; assign lsu_freeze_c2_dc4_clken = (lsu_freeze_c1_dc4_clken | lsu_freeze_c1_dc4_clken_q | clk_override) & ~lsu_freeze_dc3; - + assign lsu_stbuf_c1_clken = load_stbuf_reqvld_dc3 | store_stbuf_reqvld_dc3 | stbuf_reqvld_any | stbuf_reqvld_flushed_any | clk_override; assign lsu_rdbuf_c1_clken = lsu_ldbusreq_dc3 | ~lsu_read_buffer_empty_any | clk_override; @@ -153,10 +153,10 @@ module lsu_clkdomain assign lsu_dccm_c1_dc3_clken = ((lsu_c1_dc3_clken & addr_in_dccm_dc2) | clk_override) & ~lsu_freeze_dc3; assign lsu_pic_c1_dc3_clken = ((lsu_c1_dc3_clken & addr_in_pic_dc2) | clk_override) & ~lsu_freeze_dc3; - assign lsu_free_c1_clken = ((lsu_p.valid | lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.valid) | + assign lsu_free_c1_clken = ((lsu_p.valid | lsu_pkt_dc1.valid | lsu_pkt_dc2.valid | lsu_pkt_dc3.valid | lsu_pkt_dc4.valid | lsu_pkt_dc5.valid) | ~lsu_write_buffer_empty_any | ~lsu_stbuf_empty_any | ~lsu_read_buffer_empty_any) | clk_override; 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(free_clk), .*); @@ -200,11 +200,11 @@ module lsu_clkdomain rvclkhdr lsu_rdbuf_c1_cgc ( .en(lsu_rdbuf_c1_clken), .l1clk(lsu_rdbuf_c1_clk), .* ); rvclkhdr lsu_busm_cgc (.en(lsu_bus_clk_en), .l1clk(lsu_busm_clk), .*); - + rvclkhdr lsu_dccm_c1dc3_cgc (.en(lsu_dccm_c1_dc3_clken), .l1clk(lsu_dccm_c1_dc3_clk), .*); rvclkhdr lsu_pic_c1dc3_cgc (.en(lsu_pic_c1_dc3_clken), .l1clk(lsu_pic_c1_dc3_clk), .*); - + rvclkhdr lsu_free_cgc (.en(lsu_free_c2_clken), .l1clk(lsu_free_c2_clk), .*); - + endmodule - + diff --git a/design/lsu/lsu_dccm_ctl.sv b/design/lsu/lsu_dccm_ctl.sv index 382d757..685a66c 100644 --- a/design/lsu/lsu_dccm_ctl.sv +++ b/design/lsu/lsu_dccm_ctl.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,14 +16,14 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: DCCM for LSU pipe // Comments: Single ported memory // -// +// // DC1 -> DC2 -> DC3 -> DC4 (Commit) -// +// // //******************************************************************************** module lsu_dccm_ctl @@ -33,10 +33,10 @@ module lsu_dccm_ctl input logic lsu_freeze_c2_dc3_clk, input logic lsu_dccm_c1_dc3_clk, input logic lsu_pic_c1_dc3_clk, - + input logic rst_l, input logic lsu_freeze_dc3, // freze - + input lsu_pkt_t lsu_pkt_dc3, // lsu packets input lsu_pkt_t lsu_pkt_dc1, input logic addr_in_dccm_dc1, // address maps to dccm @@ -49,31 +49,31 @@ module lsu_dccm_ctl input logic stbuf_reqvld_any, // write enable input logic stbuf_addr_in_pic_any, // stbuf is going to pic input logic [`RV_LSU_SB_BITS-1:0] stbuf_addr_any, // stbuf address (aligned) - + input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_data_any, // the read out from stbuf - input logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // the encoded data with ECC bits + input logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, // the encoded data with ECC bits input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3, // stbuf fowarding to load input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3, // stbuf fowarding to load input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_dc3, // stbuf fowarding to load - input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3, // stbuf fowarding to load + input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3, // stbuf fowarding to load input logic lsu_double_ecc_error_dc3, // lsu has a DED input logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_hi_dc3, // store data - input logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_lo_dc3, // store data + input logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_lo_dc3, // store data output logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_hi_dc3, // data from the dccm output logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_lo_dc3, // data from the dccm output logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_dc3, // data from the dccm + ecc - output logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_dc3, + output logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_dc3, output logic [`RV_DCCM_DATA_WIDTH-1:0] lsu_ld_data_dc3, // right justified, ie load byte will have data at 7:0 output logic [31:0] picm_mask_data_dc3, // pic data to stbuf output logic lsu_stbuf_commit_any, // stbuf wins the dccm port or is to pic output logic lsu_dccm_rden_dc3, // dccm read - + output logic dccm_dma_rvalid, // dccm serviving the dma load output logic dccm_dma_ecc_error, // DMA load had ecc error output logic [63:0] dccm_dma_rdata, // dccm data to dma request - + // DCCM ports output logic dccm_wren, // dccm interface -- write output logic dccm_rden, // dccm interface -- write @@ -81,7 +81,7 @@ module lsu_dccm_ctl output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_lo, // dccm interface -- read address for lo bank output logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_hi, // dccm interface -- read address for hi bank output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_wr_data, // dccm write data - + input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // dccm read data back from the dccm input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // dccm read data back from the dccm @@ -92,12 +92,12 @@ module lsu_dccm_ctl output logic [31:0] picm_addr, // address for pic access - shared between reads and write output logic [31:0] picm_wr_data, // write data input logic [31:0] picm_rd_data, // read data - - input logic scan_mode // scan mode + + input logic scan_mode // scan mode ); `include "global.h" - + `ifdef RV_DCCM_ENABLE localparam DCCM_ENABLE = 1'b1; `else @@ -106,7 +106,7 @@ module lsu_dccm_ctl localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH); localparam PIC_BITS =`RV_PIC_BITS; - + logic lsu_dccm_rden_dc1, lsu_dccm_rden_dc2; logic [DCCM_DATA_WIDTH-1:0] dccm_data_hi_dc2, dccm_data_lo_dc2; logic [DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_dc2, dccm_data_ecc_lo_dc2; @@ -117,29 +117,29 @@ module lsu_dccm_ctl logic [63:0] picm_rd_data_dc3; logic [31:0] picm_rd_data_lo_dc3; logic [63:32] lsu_ld_data_dc3_nc; - + assign dccm_dma_rvalid = lsu_pkt_dc3.valid & lsu_pkt_dc3.load & lsu_pkt_dc3.dma; //assign dccm_dma_rdata[63:0] = dma_rdata_dc3[63:0]; assign dccm_dma_ecc_error = lsu_double_ecc_error_dc3; - + assign {lsu_ld_data_dc3_nc[63:32], lsu_ld_data_dc3[31:0]} = lsu_rdata_dc3[63:0] >> 8*lsu_addr_dc3[1:0]; - + assign dccm_dout_dc3[63:0] = {dccm_data_hi_dc3[DCCM_DATA_WIDTH-1:0], dccm_data_lo_dc3[DCCM_DATA_WIDTH-1:0]}; assign dccm_corr_dout_dc3[63:0] = {store_ecc_datafn_hi_dc3[DCCM_DATA_WIDTH-1:0], store_ecc_datafn_lo_dc3[DCCM_DATA_WIDTH-1:0]}; assign stbuf_fwddata_dc3[63:0] = {stbuf_fwddata_hi_dc3[DCCM_DATA_WIDTH-1:0], stbuf_fwddata_lo_dc3[DCCM_DATA_WIDTH-1:0]}; assign stbuf_fwdbyteen_dc3[7:0] = {stbuf_fwdbyteen_hi_dc3[DCCM_BYTE_WIDTH-1:0], stbuf_fwdbyteen_lo_dc3[DCCM_BYTE_WIDTH-1:0]}; for (genvar i=0; i<8; i++) begin: GenLoop - assign lsu_rdata_dc3[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] : + assign lsu_rdata_dc3[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] : (addr_in_pic_dc3 ? picm_rd_data_dc3[(8*i)+7:8*i] : dccm_dout_dc3[(8*i)+7:8*i]); - assign dccm_dma_rdata[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] : + assign dccm_dma_rdata[(8*i)+7:8*i] = stbuf_fwdbyteen_dc3[i] ? stbuf_fwddata_dc3[(8*i)+7:8*i] : (addr_in_pic_dc3 ? picm_rd_data_dc3[(8*i)+7:8*i] : dccm_corr_dout_dc3[(8*i)+7:8*i]); end assign lsu_stbuf_commit_any = stbuf_reqvld_any & ~lsu_freeze_dc3 & ( (~(lsu_dccm_rden_dc1 | picm_rden | picm_mken)) | ((picm_rden | picm_mken) & ~stbuf_addr_in_pic_any) | - (lsu_dccm_rden_dc1 & (stbuf_addr_in_pic_any | (~((stbuf_addr_any[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] == lsu_addr_dc1[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]) | + (lsu_dccm_rden_dc1 & (stbuf_addr_in_pic_any | (~((stbuf_addr_any[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] == lsu_addr_dc1[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]) | (stbuf_addr_any[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] == end_addr_dc1[DCCM_WIDTH_BITS+:DCCM_BANK_BITS])))))); // No need to read for aligned word/dword stores since ECC will come by new data completely @@ -164,14 +164,14 @@ module lsu_dccm_ctl assign picm_wren = lsu_stbuf_commit_any & stbuf_addr_in_pic_any; assign picm_rden = lsu_pkt_dc1.valid & lsu_pkt_dc1.load & addr_in_pic_dc1; assign picm_mken = lsu_pkt_dc1.valid & lsu_pkt_dc1.store & addr_in_pic_dc1; // Get the mask for stores - assign picm_addr[31:0] = (picm_rden | picm_mken) ? (`RV_PIC_BASE_ADDR | {17'b0,lsu_addr_dc1[14:0]}) : (`RV_PIC_BASE_ADDR | {{32-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]}); - //assign picm_addr[31:0] = (picm_rden | picm_mken) ? {`RV_PIC_REGION,`RV_PIC_OFFSET,3'b0,lsu_addr_dc1[14:0]} : {`RV_PIC_REGION,`RV_PIC_OFFSET,{18-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]}; + assign picm_addr[31:0] = (picm_rden | picm_mken) ? (`RV_PIC_BASE_ADDR | {17'b0,lsu_addr_dc1[14:0]}) : (`RV_PIC_BASE_ADDR | {{32-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]}); + //assign picm_addr[31:0] = (picm_rden | picm_mken) ? {`RV_PIC_REGION,`RV_PIC_OFFSET,3'b0,lsu_addr_dc1[14:0]} : {`RV_PIC_REGION,`RV_PIC_OFFSET,{18-PIC_BITS{1'b0}},stbuf_addr_any[`RV_PIC_BITS-1:0]}; assign picm_wr_data[31:0] = stbuf_data_any[31:0]; - - + + // Flops assign picm_mask_data_dc3[31:0] = picm_rd_data_lo_dc3[31:0]; - assign picm_rd_data_dc3[63:0] = {picm_rd_data_lo_dc3[31:0], picm_rd_data_lo_dc3[31:0]} ; + assign picm_rd_data_dc3[63:0] = {picm_rd_data_lo_dc3[31:0], picm_rd_data_lo_dc3[31:0]} ; rvdff #(32) picm_data_ff (.*, .din(picm_rd_data[31:0]), .dout(picm_rd_data_lo_dc3[31:0]), .clk(lsu_pic_c1_dc3_clk)); if (DCCM_ENABLE == 1) begin: Gen_dccm_enable rvdff #(1) dccm_rden_dc2ff (.*, .din(lsu_dccm_rden_dc1), .dout(lsu_dccm_rden_dc2), .clk(lsu_freeze_c2_dc2_clk)); @@ -179,7 +179,7 @@ module lsu_dccm_ctl rvdff #(DCCM_DATA_WIDTH) dccm_data_hi_ff (.*, .din(dccm_data_hi_dc2[DCCM_DATA_WIDTH-1:0]), .dout(dccm_data_hi_dc3[DCCM_DATA_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk)); rvdff #(DCCM_DATA_WIDTH) dccm_data_lo_ff (.*, .din(dccm_data_lo_dc2[DCCM_DATA_WIDTH-1:0]), .dout(dccm_data_lo_dc3[DCCM_DATA_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk)); - + rvdff #(DCCM_ECC_WIDTH) dccm_data_ecc_hi_ff (.*, .din(dccm_data_ecc_hi_dc2[DCCM_ECC_WIDTH-1:0]), .dout(dccm_data_ecc_hi_dc3[DCCM_ECC_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk)); rvdff #(DCCM_ECC_WIDTH) dccm_data_ecc_lo_ff (.*, .din(dccm_data_ecc_lo_dc2[DCCM_ECC_WIDTH-1:0]), .dout(dccm_data_ecc_lo_dc3[DCCM_ECC_WIDTH-1:0]), .clk(lsu_dccm_c1_dc3_clk)); end else begin: Gen_dccm_disable diff --git a/design/lsu/lsu_dccm_mem.sv b/design/lsu/lsu_dccm_mem.sv index 5597378..b95f750 100644 --- a/design/lsu/lsu_dccm_mem.sv +++ b/design/lsu/lsu_dccm_mem.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,29 +16,29 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: DCCM for LSU pipe // Comments: Single ported memory // -// +// // DC1 -> DC2 -> DC3 -> DC4 (Commit) -// +// // //******************************************************************************** module lsu_dccm_mem ( - input logic clk, // clock - input logic rst_l, + input logic clk, // clock + input logic rst_l, input logic lsu_freeze_dc3, // freeze input logic clk_override, // clock override - + input logic dccm_wren, // write enable input logic dccm_rden, // read enable input logic [`RV_DCCM_BITS-1:0] dccm_wr_addr, // write address input logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_lo, // read address input logic [`RV_DCCM_BITS-1:0] dccm_rd_addr_hi, // read address for the upper bank in case of a misaligned access input logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_wr_data, // write data - + output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // read data from the lo bank output logic [`RV_DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // read data from the hi bank @@ -46,10 +46,10 @@ module lsu_dccm_mem ( ); `include "global.h" - + localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH); localparam DCCM_INDEX_BITS = (DCCM_BITS - DCCM_BANK_BITS - DCCM_WIDTH_BITS); - + logic [DCCM_NUM_BANKS-1:0] wren_bank; logic [DCCM_NUM_BANKS-1:0] rden_bank; logic [DCCM_NUM_BANKS-1:0] [DCCM_BITS-1:(DCCM_BANK_BITS+2)] addr_bank; @@ -65,30 +65,30 @@ module lsu_dccm_mem ( logic [(DCCM_WIDTH_BITS+DCCM_BANK_BITS-1):DCCM_WIDTH_BITS] dccm_rd_addr_lo_q; logic [(DCCM_WIDTH_BITS+DCCM_BANK_BITS-1):DCCM_WIDTH_BITS] dccm_rd_addr_hi_q; - + logic [DCCM_NUM_BANKS-1:0] dccm_clk; logic [DCCM_NUM_BANKS-1:0] dccm_clken; - + assign rd_unaligned = (dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS] != dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]); - + // Align the read data assign dccm_rd_data_lo[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0]; assign dccm_rd_data_hi[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0]; // Generate even/odd address - // assign rd_addr_even[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] : + // assign rd_addr_even[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] : // dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS]; - - // assign rd_addr_odd[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] : - // dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS]; - + + // assign rd_addr_odd[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = dccm_rd_addr_lo[2] ? dccm_rd_addr_lo[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] : + // dccm_rd_addr_hi[(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS]; + // 8 Banks, 16KB each (2048 x 72) for (genvar i=0; i DC2 -> DC3 -> DC4 (Commit) -// +// //******************************************************************************** module lsu_ecc import swerv_types::*; @@ -41,34 +41,34 @@ module lsu_ecc input logic [`RV_DCCM_BITS-1:0] lsu_addr_dc3, // start address input logic [`RV_DCCM_BITS-1:0] end_addr_dc3, // end address input logic [63:0] store_data_dc3, // store data - input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_data_any, + input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_data_any, input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3, // data forward from the store buffer input logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3, // data forward from the store buffer input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_dc3,// which bytes from the store buffer are on input logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3,// which bytes from the store buffer are on - + input logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_hi_dc3, // raw data from mem input logic [`RV_DCCM_DATA_WIDTH-1:0] dccm_data_lo_dc3, // raw data from mem input logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_hi_dc3, // ecc read out from mem input logic [`RV_DCCM_ECC_WIDTH-1:0] dccm_data_ecc_lo_dc3, // ecc read out from mem input logic dec_tlu_core_ecc_disable, // disables the ecc computation and error flagging - - output logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_hi_dc3, // final store data either from stbuf or SEC DCCM readout + + output logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_hi_dc3, // final store data either from stbuf or SEC DCCM readout output logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_lo_dc3, - output logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, + output logic [`RV_DCCM_ECC_WIDTH-1:0] stbuf_ecc_any, output logic single_ecc_error_hi_dc3, // sec detected output logic single_ecc_error_lo_dc3, // sec detected on lower dccm bank output logic lsu_single_ecc_error_dc3, // or of the 2 output logic lsu_double_ecc_error_dc3, // double error detected - - input logic scan_mode + + input logic scan_mode ); `include "global.h" - + `ifdef RV_DCCM_ENABLE localparam DCCM_ENABLE = 1'b1; `else @@ -77,8 +77,8 @@ module lsu_ecc logic [DCCM_DATA_WIDTH-1:0] sec_data_hi_dc3; logic [DCCM_DATA_WIDTH-1:0] sec_data_lo_dc3; - - + + logic double_ecc_error_hi_dc3, double_ecc_error_lo_dc3; logic ldst_dual_dc3; @@ -88,12 +88,12 @@ module lsu_ecc logic [7:0] store_byteen_dc3; logic [7:0] store_byteen_ext_dc3; logic [DCCM_BYTE_WIDTH-1:0] store_byteen_hi_dc3, store_byteen_lo_dc3; - + logic [163:0] store_data_ext_dc3; - logic [DCCM_DATA_WIDTH-1:0] store_data_hi_dc3, store_data_lo_dc3; + logic [DCCM_DATA_WIDTH-1:0] store_data_hi_dc3, store_data_lo_dc3; logic [6:0] ecc_out_hi_nc, ecc_out_lo_nc; - - + + assign ldst_dual_dc3 = (lsu_addr_dc3[2] != end_addr_dc3[2]); assign is_ldst_dc3 = lsu_pkt_dc3.valid & (lsu_pkt_dc3.load | lsu_pkt_dc3.store) & addr_in_dccm_dc3 & lsu_dccm_rden_dc3; assign is_ldst_lo_dc3 = is_ldst_dc3 & ~dec_tlu_core_ecc_disable; @@ -104,7 +104,7 @@ module lsu_ecc ({8{lsu_pkt_dc3.word}} & 8'b0000_1111) | ({8{lsu_pkt_dc3.dword}} & 8'b1111_1111); assign store_byteen_dc3[7:0] = ldst_byteen_dc3[7:0] & {8{lsu_pkt_dc3.store}}; - + assign store_byteen_ext_dc3[7:0] = store_byteen_dc3[7:0] << lsu_addr_dc3[1:0]; assign store_byteen_hi_dc3[DCCM_BYTE_WIDTH-1:0] = store_byteen_ext_dc3[7:4]; assign store_byteen_lo_dc3[DCCM_BYTE_WIDTH-1:0] = store_byteen_ext_dc3[3:0]; @@ -113,7 +113,7 @@ module lsu_ecc assign store_data_hi_dc3[DCCM_DATA_WIDTH-1:0] = store_data_ext_dc3[63:32]; assign store_data_lo_dc3[DCCM_DATA_WIDTH-1:0] = store_data_ext_dc3[31:0]; - + // Merge store data and sec data // This is used for loads as well for ecc error case. store_byteen will be 0 for loads for (genvar i=0; i> {dma_mem_addr[2:0], 3'b000}; // Shift the dma data to lower bits to make it consistent to lsu stores - assign store_data_d[63:0] = dma_dccm_req ? dma_mem_wdata_shifted[63:0] : {32'b0,exu_lsu_rs2_d[31:0]}; + assign store_data_d[63:0] = dma_dccm_req ? dma_mem_wdata_shifted[63:0] : {32'b0,exu_lsu_rs2_d[31:0]}; assign store_data_dc2_in[63:32] = store_data_dc1[63:32]; - assign store_data_dc2_in[31:0] = (lsu_pkt_dc1.store_data_bypass_c1) ? lsu_result_dc3[31:0] : + assign store_data_dc2_in[31:0] = (lsu_pkt_dc1.store_data_bypass_c1) ? lsu_result_dc3[31:0] : (lsu_pkt_dc1.store_data_bypass_e4_c1[1]) ? i1_result_e4_eff[31:0] : (lsu_pkt_dc1.store_data_bypass_e4_c1[0]) ? i0_result_e4_eff[31:0] : store_data_dc1[31:0]; - + assign store_data_dc2[63:32] = store_data_pre_dc2[63:32]; assign store_data_dc2[31:0] = (lsu_pkt_dc2.store_data_bypass_i0_e2_c2) ? i0_result_e2[31:0] : - (lsu_pkt_dc2.store_data_bypass_c2) ? lsu_result_dc3[31:0] : + (lsu_pkt_dc2.store_data_bypass_c2) ? lsu_result_dc3[31:0] : (lsu_pkt_dc2.store_data_bypass_e4_c2[1]) ? i1_result_e4_eff[31:0] : (lsu_pkt_dc2.store_data_bypass_e4_c2[0]) ? i0_result_e4_eff[31:0] : store_data_pre_dc2[31:0]; assign store_data_dc3[63:32] = store_data_pre_dc3[63:32]; - assign store_data_dc3[31:0] = (picm_mask_data_dc3[31:0] | {32{~addr_in_pic_dc3}}) & + assign store_data_dc3[31:0] = (picm_mask_data_dc3[31:0] | {32{~addr_in_pic_dc3}}) & ((lsu_pkt_dc3.store_data_bypass_e4_c3[1]) ? i1_result_e4_eff[31:0] : (lsu_pkt_dc3.store_data_bypass_e4_c3[0]) ? i0_result_e4_eff[31:0] : store_data_pre_dc3[31:0]); - + rvdff #(64) sddc1ff (.*, .din(store_data_d[63:0]), .dout(store_data_dc1[63:0]), .clk(lsu_store_c1_dc1_clk)); rvdff #(64) sddc2ff (.*, .din(store_data_dc2_in[63:0]), .dout(store_data_pre_dc2[63:0]), .clk(lsu_store_c1_dc2_clk)); rvdffs #(64) sddc3ff (.*, .din(store_data_dc2[63:0]), .dout(store_data_pre_dc3[63:0]), .en(~lsu_freeze_dc3), .clk(lsu_store_c1_dc3_clk)); rvdff #(32) sddc4ff (.*, .din(store_data_dc3[31:0]), .dout(store_data_dc4[31:0]), .clk(lsu_store_c1_dc4_clk)); - rvdff #(32) sddc5ff (.*, .din(store_data_dc4[31:0]), .dout(store_data_dc5[31:0]), .clk(lsu_store_c1_dc5_clk)); - + rvdff #(32) sddc5ff (.*, .din(store_data_dc4[31:0]), .dout(store_data_dc5[31:0]), .clk(lsu_store_c1_dc5_clk)); + rvdff #(32) sadc2ff (.*, .din(lsu_addr_dc1[31:0]), .dout(lsu_addr_dc2[31:0]), .clk(lsu_freeze_c1_dc2_clk)); rvdff #(32) sadc3ff (.*, .din(lsu_addr_dc2[31:0]), .dout(lsu_addr_dc3[31:0]), .clk(lsu_freeze_c1_dc3_clk)); rvdff #(32) sadc4ff (.*, .din(lsu_addr_dc3[31:0]), .dout(lsu_addr_dc4[31:0]), .clk(lsu_c1_dc4_clk)); - rvdff #(32) sadc5ff (.*, .din(lsu_addr_dc4[31:0]), .dout(lsu_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk)); - + rvdff #(32) sadc5ff (.*, .din(lsu_addr_dc4[31:0]), .dout(lsu_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk)); + rvdff #(32) end_addr_dc2ff (.*, .din(end_addr_dc1[31:0]), .dout(end_addr_dc2[31:0]), .clk(lsu_freeze_c1_dc2_clk)); rvdff #(32) end_addr_dc3ff (.*, .din(end_addr_dc2[31:0]), .dout(end_addr_dc3[31:0]), .clk(lsu_freeze_c1_dc3_clk)); rvdff #(32) end_addr_dc4ff (.*, .din(end_addr_dc3[31:0]), .dout(end_addr_dc4[31:0]), .clk(lsu_c1_dc4_clk)); - rvdff #(32) end_addr_dc5ff (.*, .din(end_addr_dc4[31:0]), .dout(end_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk)); + rvdff #(32) end_addr_dc5ff (.*, .din(end_addr_dc4[31:0]), .dout(end_addr_dc5[31:0]), .clk(lsu_c1_dc5_clk)); rvdff #(1) addr_in_dccm_dc2ff(.din(addr_in_dccm_dc1), .dout(addr_in_dccm_dc2), .clk(lsu_freeze_c1_dc2_clk), .*); rvdff #(1) addr_in_dccm_dc3ff(.din(addr_in_dccm_dc2), .dout(addr_in_dccm_dc3), .clk(lsu_freeze_c1_dc3_clk), .*); rvdff #(1) addr_in_pic_dc2ff(.din(addr_in_pic_dc1), .dout(addr_in_pic_dc2), .clk(lsu_freeze_c1_dc2_clk), .*); rvdff #(1) addr_in_pic_dc3ff(.din(addr_in_pic_dc2), .dout(addr_in_pic_dc3), .clk(lsu_freeze_c1_dc3_clk), .*); - + rvdff #(1) addr_external_dc2ff(.din(addr_external_dc1), .dout(addr_external_dc2), .clk(lsu_freeze_c1_dc2_clk), .*); rvdff #(1) addr_external_dc3ff(.din(addr_external_dc2), .dout(addr_external_dc3), .clk(lsu_freeze_c1_dc3_clk), .*); rvdff #(1) addr_external_dc4ff(.din(addr_external_dc3), .dout(addr_external_dc4), .clk(lsu_c1_dc4_clk), .*); rvdff #(1) addr_external_dc5ff(.din(addr_external_dc4), .dout(addr_external_dc5), .clk(lsu_c1_dc5_clk), .*); - + rvdff #(1) access_fault_dc2ff(.din(access_fault_dc1), .dout(access_fault_dc2), .clk(lsu_freeze_c1_dc2_clk), .*); rvdff #(1) access_fault_dc3ff(.din(access_fault_dc2), .dout(access_fault_dc3), .clk(lsu_freeze_c1_dc3_clk), .*); rvdff #(1) misaligned_fault_dc2ff(.din(misaligned_fault_dc1), .dout(misaligned_fault_dc2), .clk(lsu_freeze_c1_dc2_clk), .*); diff --git a/design/lsu/lsu_stbuf.sv b/design/lsu/lsu_stbuf.sv index 86169fb..5f2f255 100644 --- a/design/lsu/lsu_stbuf.sv +++ b/design/lsu/lsu_stbuf.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,14 +16,14 @@ //******************************************************************************** // $Id$ // -// -// Owner: +// +// Owner: // Function: Store Buffer // Comments: Dual writes and single drain // -// +// // DC1 -> DC2 -> DC3 -> DC4 (Commit) -// +// // //******************************************************************************** @@ -34,7 +34,7 @@ module lsu_stbuf input logic rst_l, // reset input logic lsu_freeze_c2_dc2_clk, // freeze clock - input logic lsu_freeze_c2_dc3_clk, // freeze clock + input logic lsu_freeze_c2_dc3_clk, // freeze clock input logic lsu_freeze_c1_dc2_clk, // freeze clock input logic lsu_freeze_c1_dc3_clk, // freeze clock input logic lsu_c1_dc4_clk, // lsu pipe clock @@ -43,11 +43,11 @@ module lsu_stbuf input logic lsu_c2_dc5_clk, // lsu pipe clock input logic lsu_stbuf_c1_clk, // stbuf clock input logic lsu_free_c2_clk, // free clk - - // Store Buffer input + + // Store Buffer input input logic load_stbuf_reqvld_dc3, // core instruction goes to stbuf input logic store_stbuf_reqvld_dc3, // core instruction goes to stbuf - //input logic ldst_stbuf_reqvld_dc3, + //input logic ldst_stbuf_reqvld_dc3, input logic addr_in_pic_dc3, // address is in pic input logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_hi_dc3, // data to write input logic [`RV_DCCM_DATA_WIDTH-1:0] store_ecc_datafn_lo_dc3, // data to write @@ -55,14 +55,14 @@ module lsu_stbuf input logic isldst_dc1, // instruction in dc1 is lsu input logic isldst_dc2, // instruction in dc2 is lsu input logic isldst_dc3, // instruction in dc3 is lsu - + input logic single_ecc_error_hi_dc3, // single ecc error in hi bank input logic single_ecc_error_lo_dc3, // single ecc error in lo bank input logic lsu_single_ecc_error_dc5, // single_ecc_error in either bank staged to the dc5 - needed for the load repairs input logic lsu_commit_dc5, // lsu commits input logic lsu_freeze_dc3, // lsu freeze input logic flush_prior_dc5, // Flush is due to i0 and ld/st is in i1 - + // Store Buffer output output logic stbuf_reqvld_any, // stbuf is draining output logic stbuf_reqvld_flushed_any, // Top entry is flushed @@ -74,42 +74,42 @@ module lsu_stbuf input logic lsu_stbuf_commit_any, // pop the stbuf as it commite output logic lsu_stbuf_full_any, // stbuf is full output logic lsu_stbuf_empty_any, // stbuf is empty - + input logic [`RV_LSU_SB_BITS-1:0] lsu_addr_dc1, // lsu address input logic [`RV_LSU_SB_BITS-1:0] lsu_addr_dc2, input logic [`RV_LSU_SB_BITS-1:0] lsu_addr_dc3, - + input logic [`RV_LSU_SB_BITS-1:0] end_addr_dc1, // lsu end addrress - needed to check unaligned input logic [`RV_LSU_SB_BITS-1:0] end_addr_dc2, input logic [`RV_LSU_SB_BITS-1:0] end_addr_dc3, - + // Forwarding signals input logic lsu_cmpen_dc2, // needed for forwarding stbuf - load input lsu_pkt_t lsu_pkt_dc2, - input lsu_pkt_t lsu_pkt_dc3, - input lsu_pkt_t lsu_pkt_dc5, - + input lsu_pkt_t lsu_pkt_dc3, + input lsu_pkt_t lsu_pkt_dc5, + output logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_hi_dc3, // stbuf data output logic [`RV_DCCM_DATA_WIDTH-1:0] stbuf_fwddata_lo_dc3, output logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_hi_dc3, output logic [`RV_DCCM_BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_dc3, - - input logic scan_mode - + + input logic scan_mode + ); `include "global.h" - + localparam DEPTH = LSU_STBUF_DEPTH; localparam DATA_WIDTH = DCCM_DATA_WIDTH; localparam BYTE_WIDTH = DCCM_BYTE_WIDTH; localparam DEPTH_LOG2 = $clog2(DEPTH); - + logic [DEPTH-1:0] stbuf_data_vld; logic [DEPTH-1:0] stbuf_drain_vld; logic [DEPTH-1:0] stbuf_flush_vld; logic [DEPTH-1:0] stbuf_addr_in_pic; - logic [DEPTH-1:0][LSU_SB_BITS-1:0] stbuf_addr; + logic [DEPTH-1:0][LSU_SB_BITS-1:0] stbuf_addr; logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_byteen; logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_data; @@ -123,16 +123,16 @@ module lsu_stbuf logic [DEPTH-1:0][LSU_SB_BITS-1:0] stbuf_addrin; logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_datain; logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_byteenin; - + logic [7:0] ldst_byteen_dc3; logic [7:0] store_byteen_ext_dc3; logic [BYTE_WIDTH-1:0] store_byteen_hi_dc3; logic [BYTE_WIDTH-1:0] store_byteen_lo_dc3; - logic ldst_stbuf_reqvld_dc3; + logic ldst_stbuf_reqvld_dc3; logic dual_ecc_error_dc3; logic dual_stbuf_write_dc3; - + logic WrPtrEn, RdPtrEn; logic [DEPTH_LOG2-1:0] WrPtr, RdPtr; logic [DEPTH_LOG2-1:0] NxtWrPtr, NxtRdPtr; @@ -141,11 +141,11 @@ module lsu_stbuf logic ldst_dual_dc1, ldst_dual_dc2, ldst_dual_dc3, ldst_dual_dc4, ldst_dual_dc5; logic ldst_stbuf_reqvld_dc4, ldst_stbuf_reqvld_dc5; logic dual_stbuf_write_dc4, dual_stbuf_write_dc5; - + logic [3:0] stbuf_numvld_any, stbuf_specvld_any; logic [1:0] stbuf_specvld_dc1, stbuf_specvld_dc2, stbuf_specvld_dc3; logic stbuf_oneavl_any, stbuf_twoavl_any; - + logic cmpen_hi_dc2, cmpen_lo_dc2; logic [LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] cmpaddr_hi_dc2, cmpaddr_lo_dc2; @@ -155,7 +155,7 @@ module lsu_stbuf logic [BYTE_WIDTH-1:0] stbuf_fwdbyteen_lo_hi, stbuf_fwdbyteen_lo_lo; logic [DATA_WIDTH-1:0] stbuf_fwddata_hi_hi, stbuf_fwddata_hi_lo; logic [DATA_WIDTH-1:0] stbuf_fwddata_lo_hi, stbuf_fwddata_lo_lo; - + logic [DEPTH-1:0] stbuf_ldmatch_hi, stbuf_ldmatch_lo; logic [DEPTH-1:0][BYTE_WIDTH-1:0] stbuf_fwdbyteenvec_hi, stbuf_fwdbyteenvec_lo; logic [DEPTH-1:0][DATA_WIDTH-1:0] stbuf_fwddatavec_hi, stbuf_fwddatavec_lo; @@ -205,7 +205,7 @@ module lsu_stbuf assign stbuf_addrin[i][LSU_SB_BITS-1:0] = sel_lo[i] ? lsu_addr_dc3[LSU_SB_BITS-1:0] : end_addr_dc3[LSU_SB_BITS-1:0]; assign stbuf_byteenin[i][BYTE_WIDTH-1:0] = sel_lo[i] ? store_byteen_lo_dc3[BYTE_WIDTH-1:0] : store_byteen_hi_dc3[BYTE_WIDTH-1:0]; assign stbuf_datain[i][DATA_WIDTH-1:0] = sel_lo[i] ? store_ecc_datafn_lo_dc3[DATA_WIDTH-1:0] : store_ecc_datafn_hi_dc3[DATA_WIDTH-1:0]; - + rvdffsc #(.WIDTH(1)) stbuf_data_vldff (.din(1'b1), .dout(stbuf_data_vld[i]), .en(stbuf_wr_en[i]), .clear(stbuf_reset[i]), .clk(lsu_stbuf_c1_clk), .*); rvdffsc #(.WIDTH(1)) stbuf_drain_vldff (.din(1'b1), .dout(stbuf_drain_vld[i]), .en(stbuf_drain_en[i]), .clear(stbuf_reset[i]), .clk(lsu_free_c2_clk), .*); rvdffsc #(.WIDTH(1)) stbuf_flush_vldff (.din(1'b1), .dout(stbuf_flush_vld[i]), .en(stbuf_flush_en[i]), .clear(stbuf_reset[i]), .clk(lsu_free_c2_clk), .*); @@ -263,7 +263,7 @@ module lsu_stbuf assign lsu_stbuf_full_any = (stbuf_specvld_any[3:0] > (DEPTH - 2)); assign lsu_stbuf_empty_any = (stbuf_numvld_any[3:0] == 4'b0); - + assign stbuf_oneavl_any = (stbuf_numvld_any[3:0] < DEPTH); assign stbuf_twoavl_any = (stbuf_numvld_any[3:0] < (DEPTH - 1)); @@ -273,7 +273,7 @@ module lsu_stbuf assign cmpen_lo_dc2 = lsu_cmpen_dc2; assign cmpaddr_lo_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] = lsu_addr_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]; - + // JIT forwarding assign stbuf_ldmatch_hi_hi = (end_addr_dc3[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & ~(cmpen_hi_dc2 & lsu_pkt_dc2.dma & ~lsu_pkt_dc3.dma); assign stbuf_ldmatch_hi_lo = (lsu_addr_dc3[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)] == cmpaddr_hi_dc2[LSU_SB_BITS-1:$clog2(BYTE_WIDTH)]) & ~(cmpen_hi_dc2 & lsu_pkt_dc2.dma & ~lsu_pkt_dc3.dma); @@ -285,27 +285,27 @@ module lsu_stbuf assign stbuf_fwdbyteen_hi_lo[i] = stbuf_ldmatch_hi_lo & store_byteen_lo_dc3[i] & ldst_stbuf_reqvld_dc3; assign stbuf_fwdbyteen_lo_hi[i] = stbuf_ldmatch_lo_hi & store_byteen_hi_dc3[i] & ldst_stbuf_reqvld_dc3 & dual_stbuf_write_dc3; assign stbuf_fwdbyteen_lo_lo[i] = stbuf_ldmatch_lo_lo & store_byteen_lo_dc3[i] & ldst_stbuf_reqvld_dc3; - + assign stbuf_fwddata_hi_hi[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_hi_hi[i]}} & store_ecc_datafn_hi_dc3[(8*i)+7:(8*i)]; assign stbuf_fwddata_hi_lo[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_hi_lo[i]}} & store_ecc_datafn_lo_dc3[(8*i)+7:(8*i)]; assign stbuf_fwddata_lo_hi[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_lo_hi[i]}} & store_ecc_datafn_hi_dc3[(8*i)+7:(8*i)]; assign stbuf_fwddata_lo_lo[(8*i)+7:(8*i)] = {8{stbuf_fwdbyteen_lo_lo[i]}} & store_ecc_datafn_lo_dc3[(8*i)+7:(8*i)]; end - + always_comb begin: GenLdFwd stbuf_fwdbyteen_hi_dc2[BYTE_WIDTH-1:0] = '0; stbuf_fwdbyteen_lo_dc2[BYTE_WIDTH-1:0] = '0; for (int i=0; i meipt_inv[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)); @@ -394,18 +394,18 @@ module pic_ctrl // assign atleast_one_int_enabled_in = |intenable_reg[TOTAL_INT-1:0] ; // rvdff #(1) one_int_en_ff (.*, .din (atleast_one_int_enabled_in), .dout(atleast_one_int_enabled)); - // + // // assign mexintpend = mexintpend_unq & atleast_one_int_enabled ; // assign mhwakeup = mhwakeup_unq & atleast_one_int_enabled ; ////////////////////////////////////////////////////////////////////////// - // Reads of register. + // Reads of register. // 1- intpending ////////////////////////////////////////////////////////////////////////// - assign intpend_reg_read = addr_intpend_base_match & picm_rden_ff ; + assign intpend_reg_read = addr_intpend_base_match & picm_rden_ff ; assign intpriority_reg_read = addr_intpriority_base_match & picm_rden_ff; assign intenable_reg_read = addr_intenable_base_match & picm_rden_ff; assign gw_config_reg_read = addr_config_gw_base_match & picm_rden_ff; @@ -416,14 +416,14 @@ module pic_ctrl assign intpend_rd_part_out[i] = (({32{intpend_reg_read & picm_addr_ff[5:2] == i}}) & intpend_reg_extended[((32*i)+31):(32*i)]) ; end - always_comb begin : INTPEND_RD + always_comb begin : INTPEND_RD intpend_rd_out = '0 ; for (int i=0; i AHB Gasket for LSU axi4_to_ahb #(.TAG(LSU_BUS_TAG)) lsu_axi4_to_ahb ( .clk_override(dec_tlu_bus_clk_override), - .bus_clk_en(lsu_bus_clk_en), + .bus_clk_en(lsu_bus_clk_en), // AXI Write Channels .axi_awvalid(lsu_axi_awvalid), @@ -1059,13 +1059,13 @@ module swerv .axi_awaddr(lsu_axi_awaddr[31:0]), .axi_awsize(lsu_axi_awsize[2:0]), .axi_awprot(lsu_axi_awprot[2:0]), - - .axi_wvalid(lsu_axi_wvalid), + + .axi_wvalid(lsu_axi_wvalid), .axi_wready(lsu_axi_wready), .axi_wdata(lsu_axi_wdata[63:0]), .axi_wstrb(lsu_axi_wstrb[7:0]), .axi_wlast(lsu_axi_wlast), - + .axi_bvalid(lsu_axi_bvalid), .axi_bready(lsu_axi_bready), .axi_bresp(lsu_axi_bresp[1:0]), @@ -1075,10 +1075,10 @@ module swerv .axi_arvalid(lsu_axi_arvalid), .axi_arready(lsu_axi_arready), .axi_arid(lsu_axi_arid[LSU_BUS_TAG-1:0]), - .axi_araddr(lsu_axi_araddr[31:0]), + .axi_araddr(lsu_axi_araddr[31:0]), .axi_arsize(lsu_axi_arsize[2:0]), .axi_arprot(lsu_axi_arprot[2:0]), - + .axi_rvalid(lsu_axi_rvalid), .axi_rready(lsu_axi_rready), .axi_rid(lsu_axi_rid[LSU_BUS_TAG-1:0]), @@ -1098,14 +1098,14 @@ module swerv .ahb_hrdata(lsu_hrdata[63:0]), .ahb_hready(lsu_hready), .ahb_hresp(lsu_hresp), - + .* ); // AXI4 -> AHB Gasket for System Bus axi4_to_ahb #(.TAG(SB_BUS_TAG)) sb_axi4_to_ahb ( .clk_override(dec_tlu_bus_clk_override), - .bus_clk_en(dbg_bus_clk_en), + .bus_clk_en(dbg_bus_clk_en), // AXI Write Channels .axi_awvalid(sb_axi_awvalid), @@ -1114,13 +1114,13 @@ module swerv .axi_awaddr(sb_axi_awaddr[31:0]), .axi_awsize(sb_axi_awsize[2:0]), .axi_awprot(sb_axi_awprot[2:0]), - - .axi_wvalid(sb_axi_wvalid), + + .axi_wvalid(sb_axi_wvalid), .axi_wready(sb_axi_wready), .axi_wdata(sb_axi_wdata[63:0]), .axi_wstrb(sb_axi_wstrb[7:0]), .axi_wlast(sb_axi_wlast), - + .axi_bvalid(sb_axi_bvalid), .axi_bready(sb_axi_bready), .axi_bresp(sb_axi_bresp[1:0]), @@ -1130,10 +1130,10 @@ module swerv .axi_arvalid(sb_axi_arvalid), .axi_arready(sb_axi_arready), .axi_arid(sb_axi_arid[SB_BUS_TAG-1:0]), - .axi_araddr(sb_axi_araddr[31:0]), + .axi_araddr(sb_axi_araddr[31:0]), .axi_arsize(sb_axi_arsize[2:0]), .axi_arprot(sb_axi_arprot[2:0]), - + .axi_rvalid(sb_axi_rvalid), .axi_rready(sb_axi_rready), .axi_rid(sb_axi_rid[SB_BUS_TAG-1:0]), @@ -1153,7 +1153,7 @@ module swerv .ahb_hrdata(sb_hrdata[63:0]), .ahb_hready(sb_hready), .ahb_hresp(sb_hresp), - + .* ); @@ -1161,8 +1161,8 @@ module swerv .clk(clk), .clk_override(dec_tlu_bus_clk_override), .bus_clk_en(ifu_bus_clk_en), - - // AHB-Lite signals + + // AHB-Lite signals .ahb_haddr(haddr[31:0]), .ahb_hburst(hburst), .ahb_hmastlock(hmastlock), @@ -1175,7 +1175,7 @@ module swerv .ahb_hrdata(hrdata[63:0]), .ahb_hready(hready), .ahb_hresp(hresp), - + // AXI Write Channels .axi_awvalid(ifu_axi_awvalid), .axi_awready(ifu_axi_awready), @@ -1183,13 +1183,13 @@ module swerv .axi_awaddr(ifu_axi_awaddr[31:0]), .axi_awsize(ifu_axi_awsize[2:0]), .axi_awprot(ifu_axi_awprot[2:0]), - - .axi_wvalid(ifu_axi_wvalid), + + .axi_wvalid(ifu_axi_wvalid), .axi_wready(ifu_axi_wready), .axi_wdata(ifu_axi_wdata[63:0]), .axi_wstrb(ifu_axi_wstrb[7:0]), .axi_wlast(ifu_axi_wlast), - + .axi_bvalid(ifu_axi_bvalid), .axi_bready(ifu_axi_bready), .axi_bresp(ifu_axi_bresp[1:0]), @@ -1199,10 +1199,10 @@ module swerv .axi_arvalid(ifu_axi_arvalid), .axi_arready(ifu_axi_arready), .axi_arid(ifu_axi_arid[IFU_BUS_TAG-1:0]), - .axi_araddr(ifu_axi_araddr[31:0]), + .axi_araddr(ifu_axi_araddr[31:0]), .axi_arsize(ifu_axi_arsize[2:0]), .axi_arprot(ifu_axi_arprot[2:0]), - + .axi_rvalid(ifu_axi_rvalid), .axi_rready(ifu_axi_rready), .axi_rid(ifu_axi_rid[IFU_BUS_TAG-1:0]), @@ -1211,7 +1211,7 @@ module swerv .axi_rlast(ifu_axi_rlast), .* ); - + //AHB -> AXI4 Gasket for DMA ahb_to_axi4 #(.TAG(DMA_BUS_TAG)) dma_ahb_to_axi4 ( .clk_override(dec_tlu_bus_clk_override), @@ -1224,35 +1224,35 @@ module swerv .axi_awaddr(dma_axi_awaddr[31:0]), .axi_awsize(dma_axi_awsize[2:0]), .axi_awprot(dma_axi_awprot[2:0]), - .axi_awlen(dma_axi_awlen[7:0]), + .axi_awlen(dma_axi_awlen[7:0]), .axi_awburst(dma_axi_awburst[1:0]), - - .axi_wvalid(dma_axi_wvalid), + + .axi_wvalid(dma_axi_wvalid), .axi_wready(dma_axi_wready), .axi_wdata(dma_axi_wdata[63:0]), .axi_wstrb(dma_axi_wstrb[7:0]), .axi_wlast(dma_axi_wlast), - + .axi_bvalid(dma_axi_bvalid), .axi_bready(dma_axi_bready), .axi_bresp(dma_axi_bresp[1:0]), - .axi_bid(dma_axi_bid[DMA_BUS_TAG-1:0]), - + .axi_bid(dma_axi_bid[DMA_BUS_TAG-1:0]), + // AXI Read Channels .axi_arvalid(dma_axi_arvalid), .axi_arready(dma_axi_arready), .axi_arid(dma_axi_arid[DMA_BUS_TAG-1:0]), - .axi_araddr(dma_axi_araddr[31:0]), + .axi_araddr(dma_axi_araddr[31:0]), .axi_arsize(dma_axi_arsize[2:0]), .axi_arprot(dma_axi_arprot[2:0]), - .axi_arlen(dma_axi_arlen[7:0]), + .axi_arlen(dma_axi_arlen[7:0]), .axi_arburst(dma_axi_arburst[1:0]), - + .axi_rvalid(dma_axi_rvalid), .axi_rready(dma_axi_rready), .axi_rid(dma_axi_rid[DMA_BUS_TAG-1:0]), .axi_rdata(dma_axi_rdata[63:0]), - .axi_rresp(dma_axi_rresp[1:0]), + .axi_rresp(dma_axi_rresp[1:0]), // AHB signals .ahb_haddr(dma_haddr[31:0]), @@ -1267,7 +1267,7 @@ module swerv .ahb_hrdata(dma_hrdata[63:0]), .ahb_hready(dma_hready), .ahb_hresp(dma_hresp), - + .* ); @@ -1282,7 +1282,7 @@ module swerv ((lsu_hsize[2:0] == 3'h2) & (lsu_haddr[1:0] == 2'b0)) | ((lsu_hsize[2:0] == 3'h3) & (lsu_haddr[2:0] == 3'b0))); endproperty - assert_ahb_trxn_aligned: assert property (ahb_trxn_aligned) else + assert_ahb_trxn_aligned: assert property (ahb_trxn_aligned) else $display("Assertion ahb_trxn_aligned failed: lsu_htrans=2'h%h, lsu_hsize=3'h%h, lsu_haddr=32'h%h",lsu_htrans[1:0], lsu_hsize[2:0], lsu_haddr[31:0]); property dma_trxn_aligned; @@ -1291,7 +1291,7 @@ module swerv ((dma_hsize[2:0] == 3'h2) & (dma_haddr[1:0] == 2'b0)) | ((dma_hsize[2:0] == 3'h3) & (dma_haddr[2:0] == 3'b0))); endproperty - //assert_dma_trxn_aligned: assert property (dma_trxn_aligned) else + //assert_dma_trxn_aligned: assert property (dma_trxn_aligned) else // $display("Assertion dma_trxn_aligned failed: dma_htrans=2'h%h, dma_hsize=3'h%h, dma_haddr=32'h%h",dma_htrans[1:0], dma_hsize[2:0], dma_haddr[31:0]); `endif @@ -1300,33 +1300,33 @@ module swerv // unpack packet // also need retires_p==3 - + assign trace_rv_i_insn_ip[63:0] = trace_rv_trace_pkt.trace_rv_i_insn_ip[63:0]; - + assign trace_rv_i_address_ip[63:0] = trace_rv_trace_pkt.trace_rv_i_address_ip[63:0]; - + assign trace_rv_i_valid_ip[2:0] = trace_rv_trace_pkt.trace_rv_i_valid_ip[2:0]; - + assign trace_rv_i_exception_ip[2:0] = trace_rv_trace_pkt.trace_rv_i_exception_ip[2:0]; - + assign trace_rv_i_ecause_ip[4:0] = trace_rv_trace_pkt.trace_rv_i_ecause_ip[4:0]; - + assign trace_rv_i_interrupt_ip[2:0] = trace_rv_trace_pkt.trace_rv_i_interrupt_ip[2:0]; - + assign trace_rv_i_tval_ip[31:0] = trace_rv_trace_pkt.trace_rv_i_tval_ip[31:0]; // constants should be hooked up at platform level // trace_rv_i_context_ip = '0; // trace_rv_i_privilege_ip = {3{4'b0011}}; - // trace_rv_i_status_ip = '0; + // trace_rv_i_status_ip = '0; // trace_rv_i_user_ip = '0; // trace_rv_halted_ip = o_cpu_halt_status; hook this up at platform level - - - + + + endmodule // swerv diff --git a/design/swerv_wrapper.sv b/design/swerv_wrapper.sv index ec10542..5c6b1bc 100644 --- a/design/swerv_wrapper.sv +++ b/design/swerv_wrapper.sv @@ -1,12 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,7 +17,7 @@ // $Id$ // // Function: Top wrapper file with swerv/mem instantiated inside -// Comments: +// Comments: // //******************************************************************************** `include "build.h" @@ -28,7 +28,7 @@ module swerv_wrapper input logic rst_l, input logic [31:1] rst_vec, input logic nmi_int, - input logic [31:1] nmi_vec, + input logic [31:1] nmi_vec, output logic [63:0] trace_rv_i_insn_ip, @@ -56,19 +56,19 @@ module swerv_wrapper output logic [3:0] lsu_axi_awcache, output logic [2:0] lsu_axi_awprot, output logic [3:0] lsu_axi_awqos, - - output logic lsu_axi_wvalid, + + output logic lsu_axi_wvalid, input logic lsu_axi_wready, output logic [63:0] lsu_axi_wdata, output logic [7:0] lsu_axi_wstrb, output logic lsu_axi_wlast, - + input logic lsu_axi_bvalid, output logic lsu_axi_bready, input logic [1:0] lsu_axi_bresp, input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic lsu_axi_arvalid, input logic lsu_axi_arready, output logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_arid, @@ -81,14 +81,14 @@ module swerv_wrapper output logic [3:0] lsu_axi_arcache, output logic [2:0] lsu_axi_arprot, output logic [3:0] lsu_axi_arqos, - + input logic lsu_axi_rvalid, output logic lsu_axi_rready, input logic [`RV_LSU_BUS_TAG-1:0] lsu_axi_rid, input logic [63:0] lsu_axi_rdata, input logic [1:0] lsu_axi_rresp, input logic lsu_axi_rlast, - + //-------------------------- IFU AXI signals-------------------------- // AXI Write Channels output logic ifu_axi_awvalid, @@ -103,19 +103,19 @@ module swerv_wrapper output logic [3:0] ifu_axi_awcache, output logic [2:0] ifu_axi_awprot, output logic [3:0] ifu_axi_awqos, - - output logic ifu_axi_wvalid, + + output logic ifu_axi_wvalid, input logic ifu_axi_wready, output logic [63:0] ifu_axi_wdata, output logic [7:0] ifu_axi_wstrb, output logic ifu_axi_wlast, - + input logic ifu_axi_bvalid, output logic ifu_axi_bready, input logic [1:0] ifu_axi_bresp, input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic ifu_axi_arvalid, input logic ifu_axi_arready, output logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_arid, @@ -128,7 +128,7 @@ module swerv_wrapper output logic [3:0] ifu_axi_arcache, output logic [2:0] ifu_axi_arprot, output logic [3:0] ifu_axi_arqos, - + input logic ifu_axi_rvalid, output logic ifu_axi_rready, input logic [`RV_IFU_BUS_TAG-1:0] ifu_axi_rid, @@ -150,19 +150,19 @@ module swerv_wrapper output logic [3:0] sb_axi_awcache, output logic [2:0] sb_axi_awprot, output logic [3:0] sb_axi_awqos, - - output logic sb_axi_wvalid, + + output logic sb_axi_wvalid, input logic sb_axi_wready, output logic [63:0] sb_axi_wdata, output logic [7:0] sb_axi_wstrb, output logic sb_axi_wlast, - + input logic sb_axi_bvalid, output logic sb_axi_bready, input logic [1:0] sb_axi_bresp, input logic [`RV_SB_BUS_TAG-1:0] sb_axi_bid, - - // AXI Read Channels + + // AXI Read Channels output logic sb_axi_arvalid, input logic sb_axi_arready, output logic [`RV_SB_BUS_TAG-1:0] sb_axi_arid, @@ -175,7 +175,7 @@ module swerv_wrapper output logic [3:0] sb_axi_arcache, output logic [2:0] sb_axi_arprot, output logic [3:0] sb_axi_arqos, - + input logic sb_axi_rvalid, output logic sb_axi_rready, input logic [`RV_SB_BUS_TAG-1:0] sb_axi_rid, @@ -195,12 +195,12 @@ module swerv_wrapper input logic [1:0] dma_axi_awburst, - input logic dma_axi_wvalid, + input logic dma_axi_wvalid, output logic dma_axi_wready, input logic [63:0] dma_axi_wdata, input logic [7:0] dma_axi_wstrb, input logic dma_axi_wlast, - + output logic dma_axi_bvalid, input logic dma_axi_bready, output logic [1:0] dma_axi_bresp, @@ -210,7 +210,7 @@ module swerv_wrapper input logic dma_axi_arvalid, output logic dma_axi_arready, input logic [`RV_DMA_BUS_TAG-1:0] dma_axi_arid, - input logic [31:0] dma_axi_araddr, + input logic [31:0] dma_axi_araddr, input logic [2:0] dma_axi_arsize, input logic [2:0] dma_axi_arprot, input logic [7:0] dma_axi_arlen, @@ -222,7 +222,7 @@ module swerv_wrapper output logic [63:0] dma_axi_rdata, output logic [1:0] dma_axi_rresp, output logic dma_axi_rlast, - + `endif `ifdef RV_BUILD_AHB_LITE @@ -261,11 +261,11 @@ module swerv_wrapper output logic [1:0] sb_htrans, output logic sb_hwrite, output logic [63:0] sb_hwdata, - + input logic [63:0] sb_hrdata, input logic sb_hready, input logic sb_hresp, - + // DMA Slave input logic [31:0] dma_haddr, input logic [2:0] dma_hburst, @@ -287,9 +287,9 @@ module swerv_wrapper input logic lsu_bus_clk_en, // Clock ratio b/w cpu core clk & AHB master interface input logic ifu_bus_clk_en, // Clock ratio b/w cpu core clk & AHB master interface input logic dbg_bus_clk_en, // Clock ratio b/w cpu core clk & AHB master interface - input logic dma_bus_clk_en, // Clock ratio b/w cpu core clk & AHB slave interface + input logic dma_bus_clk_en, // Clock ratio b/w cpu core clk & AHB slave interface + - // input logic ext_int, input logic timer_int, input logic [`RV_PIC_TOTAL_INT:1] extintsrc_req, @@ -299,9 +299,9 @@ module swerv_wrapper output logic dec_tlu_perfcnt2, output logic dec_tlu_perfcnt3, - // ports added by the soc team + // ports added by the soc team input logic jtag_tck, // JTAG clk - input logic jtag_tms, // JTAG TMS + input logic jtag_tms, // JTAG TMS input logic jtag_tdi, // JTAG tdi input logic jtag_trst_n, // JTAG Reset output logic jtag_tdo, // JTAG TDO @@ -312,10 +312,10 @@ module swerv_wrapper input logic i_cpu_run_req, // Async restart req to CPU output logic o_cpu_run_ack, // Core response to run req input logic scan_mode, // To enable scan mode - input logic mbist_mode // to enable mbist + input logic mbist_mode // to enable mbist ); -`include "global.h" +`include "global.h" // DCCM ports logic dccm_wren; @@ -324,7 +324,7 @@ module swerv_wrapper logic [DCCM_BITS-1:0] dccm_rd_addr_lo; logic [DCCM_BITS-1:0] dccm_rd_addr_hi; logic [DCCM_FDATA_WIDTH-1:0] dccm_wr_data; - + logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo; logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi; @@ -333,40 +333,40 @@ module swerv_wrapper // PIC ports // Icache & Itag ports - logic [31:4] ic_rw_addr; + logic [31:4] ic_rw_addr; logic [3:0] ic_wr_en ; // Which way to write logic ic_rd_en ; - logic [3:0] ic_tag_valid; // Valid from the I$ tag valid outside (in flops). + logic [3:0] ic_tag_valid; // Valid from the I$ tag valid outside (in flops). logic [3:0] ic_rd_hit; // ic_rd_hit[3:0] logic ic_tag_perr; // Ic tag parity error - logic [15:2] ic_debug_addr; // Read/Write addresss to the Icache. + logic [15:2] ic_debug_addr; // Read/Write addresss to the Icache. logic ic_debug_rd_en; // Icache debug rd logic ic_debug_wr_en; // Icache debug wr logic ic_debug_tag_array; // Debug tag array logic [3:0] ic_debug_way; // Debug way. Rd or Wr. `ifdef RV_ICACHE_ECC - logic [24:0] ictag_debug_rd_data;// Debug icache tag. + logic [24:0] ictag_debug_rd_data;// Debug icache tag. logic [167:0] ic_wr_data; // ic_wr_data[135:0] logic [167:0] ic_rd_data; // ic_rd_data[135:0] - logic [41:0] ic_debug_wr_data; // Debug wr cache. + logic [41:0] ic_debug_wr_data; // Debug wr cache. `else - logic [20:0] ictag_debug_rd_data;// Debug icache tag. + logic [20:0] ictag_debug_rd_data;// Debug icache tag. logic [135:0] ic_wr_data; // ic_wr_data[135:0] logic [135:0] ic_rd_data; // ic_rd_data[135:0] - logic [33:0] ic_debug_wr_data; // Debug wr cache. + logic [33:0] ic_debug_wr_data; // Debug wr cache. `endif logic [127:0] ic_premux_data; logic ic_sel_premux_data; -`ifdef RV_ICCM_ENABLE +`ifdef RV_ICCM_ENABLE // ICCM ports - logic [`RV_ICCM_BITS-1:2] iccm_rw_addr; + logic [`RV_ICCM_BITS-1:2] iccm_rw_addr; logic iccm_wren; logic iccm_rden; logic [2:0] iccm_wr_size; @@ -374,24 +374,24 @@ module swerv_wrapper logic [155:0] iccm_rd_data; `endif - logic core_rst_l; // Core reset including rst_l and dbg_rst_l + logic core_rst_l; // Core reset including rst_l and dbg_rst_l logic jtag_tdoEn; - + logic dccm_clk_override; logic icm_clk_override; logic dec_tlu_core_ecc_disable; - + // Instantiate the swerv core swerv swerv ( .* ); - + // Instantiate the mem mem mem ( .rst_l(core_rst_l), .* ); - - + + endmodule - +