risc core and wishbone domain seperated + Stagging FF added at wishbone interconnect
diff --git a/verilog/dv/risc_boot/risc_boot.c b/verilog/dv/risc_boot/risc_boot.c index d042822..f0d8010 100644 --- a/verilog/dv/risc_boot/risc_boot.c +++ b/verilog/dv/risc_boot/risc_boot.c
@@ -170,7 +170,6 @@ // Add some delay for user core to boot for(i = 0; i < 40; i ++); - for(i = 0; i < 40; i ++); if(reg_mprj_globl_reg6 != 0x11223344) bFail = 1; if(reg_mprj_globl_reg7 != 0x22334455) bFail = 1;
diff --git a/verilog/dv/risc_boot/risc_boot_tb.v b/verilog/dv/risc_boot/risc_boot_tb.v index 80c7d98..fe5a499 100644 --- a/verilog/dv/risc_boot/risc_boot_tb.v +++ b/verilog/dv/risc_boot/risc_boot_tb.v
@@ -91,7 +91,7 @@ $dumpfile("simx.vcd"); $dumpvars(1,risc_boot_tb); //$dumpvars(2,risc_boot_tb.uut); - $dumpvars(1,risc_boot_tb.uut.mprj.u_core); + $dumpvars(4,risc_boot_tb.uut.mprj.u_core); //$dumpvars(0,risc_boot_tb.u_user_spiflash); $display("Waveform Dump started"); end @@ -100,7 +100,7 @@ initial begin // Repeat cycles of 1000 clock edges as needed to complete testbench - repeat (600) begin + repeat (200) begin repeat (1000) @(posedge clock); // $display("+1000 cycles"); end
diff --git a/verilog/dv/user_risc_boot/uprj_netlists.v b/verilog/dv/user_risc_boot/uprj_netlists.v index 45af4a9..fe938c1 100644 --- a/verilog/dv/user_risc_boot/uprj_netlists.v +++ b/verilog/dv/user_risc_boot/uprj_netlists.v
@@ -38,6 +38,7 @@ `include "digital_core/src/glbl_cfg.sv" `include "digital_core/src/digital_core.sv" + `include "lib/wb_stagging.sv" `include "wb_interconnect/src/wb_arb.sv" `include "wb_interconnect/src/wb_interconnect.sv"
diff --git a/verilog/dv/user_risc_boot/user_risc_boot.hex b/verilog/dv/user_risc_boot/user_risc_boot.hex index 1fdd96c..5ab43fa 100755 --- a/verilog/dv/user_risc_boot/user_risc_boot.hex +++ b/verilog/dv/user_risc_boot/user_risc_boot.hex
@@ -38,20 +38,20 @@ 93 08 00 00 13 09 00 00 93 09 00 00 13 0A 00 00 93 0A 00 00 13 0B 00 00 93 0B 00 00 13 0C 00 00 93 0C 00 00 13 0D 00 00 93 0D 00 00 13 0E 00 00 -93 0E 00 00 13 0F 00 00 93 0F 00 00 97 01 48 00 -93 81 41 62 13 05 00 40 97 05 48 00 93 85 85 D7 -17 06 48 00 13 06 06 E3 63 0D B5 00 29 A0 14 41 -94 C1 11 05 91 05 E3 9C C5 FE 17 06 48 00 13 06 -66 E1 97 05 48 00 93 85 E5 E0 21 A0 23 20 06 00 -11 06 E3 9D C5 FE 17 01 49 00 13 01 A1 D3 17 05 -48 00 13 05 25 DF 17 06 48 00 13 06 A6 DE B3 05 -A6 40 17 07 49 00 13 07 E7 91 33 02 B7 40 92 85 -17 06 48 00 13 06 06 DD 29 A0 14 41 94 C1 11 05 +93 0E 00 00 13 0F 00 00 93 0F 00 00 97 01 00 20 +93 81 41 62 13 05 00 40 97 05 00 20 93 85 85 D7 +17 06 00 20 13 06 06 E3 63 0D B5 00 29 A0 14 41 +94 C1 11 05 91 05 E3 9C C5 FE 17 06 00 20 13 06 +66 E1 97 05 00 20 93 85 E5 E0 21 A0 23 20 06 00 +11 06 E3 9D C5 FE 17 01 01 20 13 01 A1 D3 17 05 +00 20 13 05 25 DF 17 06 00 20 13 06 A6 DE B3 05 +A6 40 17 07 01 20 13 07 E7 91 33 02 B7 40 92 85 +17 06 00 20 13 06 06 DD 29 A0 14 41 94 C1 11 05 91 05 E3 1C C5 FE 21 A0 23 A0 05 00 91 05 E3 9D E5 FE B7 02 49 00 05 43 23 A0 62 00 B7 02 49 00 91 02 13 03 30 06 23 A0 62 00 B7 02 49 00 C1 02 7D 53 23 A0 62 00 23 A2 62 00 01 45 81 45 97 02 -48 00 E7 80 22 CC 97 02 48 00 93 82 A2 D1 6D 71 +00 20 E7 80 22 CC 97 02 00 20 93 82 A2 D1 6D 71 06 C2 0A C4 0E C6 12 C8 16 CA 1A CC 1E CE 22 D0 26 D2 2A D4 2E D6 32 D8 36 DA 3A DC 3E DE C2 C0 C6 C2 CA C4 CE C6 D2 C8 D6 CA DA CC DE CE E2 D0 @@ -70,7 +70,7 @@ 66 55 D4 D3 93 08 88 78 37 9E 77 66 23 A4 17 03 93 0E 9E 89 23 A6 D7 03 01 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -97 02 B8 FF 93 82 42 09 82 82 13 00 00 00 13 00 +97 02 00 E0 93 82 42 09 82 82 13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/verilog/rtl/digital_core/src/digital_core.sv b/verilog/rtl/digital_core/src/digital_core.sv index 82df8cd..7ae0a6b 100644 --- a/verilog/rtl/digital_core/src/digital_core.sv +++ b/verilog/rtl/digital_core/src/digital_core.sv
@@ -73,7 +73,7 @@ inout vssd2, // User area 2 digital ground `endif input logic wb_clk_i , // System clock - input logic rtc_clk , // Real-time clock + input logic user_clock2 , // user Clock input logic wb_rst_i , // Regular Reset signal input logic wbd_ext_cyc_i , // strobe/request @@ -301,7 +301,7 @@ `endif // SCR1_DBG_EN // Clock - .clk (wb_clk_i ), + .core_clk (cpu_clk ), .rtc_clk (rtc_clk ), // Fuses @@ -332,6 +332,9 @@ .tdo_en (tdo_en ), `endif // SCR1_DBG_EN + + .wb_rst_n (wb_rst_n ), + .wb_clk (wb_clk_i ), // Instruction memory interface .wbd_imem_stb_o (wbd_riscv_imem_stb_i ), .wbd_imem_adr_o (wbd_riscv_imem_adr_i ), @@ -534,6 +537,7 @@ .mclk (wb_clk_i ), .reset_n (wb_rst_n ), + .user_clock2 (user_clock2 ), .device_idcode ( ), // Reg Bus Interface Signal @@ -550,6 +554,8 @@ // SDRAM Clock .sdram_clk (sdram_clk ), + .cpu_clk (cpu_clk ), + .rtc_clk (rtc_clk ), // reset .cpu_rst_n (cpu_rst_n ),
diff --git a/verilog/rtl/digital_core/src/glbl_cfg.sv b/verilog/rtl/digital_core/src/glbl_cfg.sv index 6844c9f..22e68c5 100644 --- a/verilog/rtl/digital_core/src/glbl_cfg.sv +++ b/verilog/rtl/digital_core/src/glbl_cfg.sv
@@ -48,6 +48,7 @@ module glbl_cfg ( input logic mclk, + input logic user_clock2, input logic reset_n, output logic [31:0] device_idcode, @@ -65,6 +66,8 @@ // SDRAM Clock output logic sdram_clk, + output logic cpu_clk, + output logic rtc_clk, // reset output logic cpu_rst_n, @@ -110,7 +113,6 @@ logic reg_cs_l ; logic reg_cs_2l ; -logic cfg_sdram_clk_div; logic [31:0] reg_0; // Software_Reg_0 @@ -252,12 +254,24 @@ // reg-0 // ----------------------------------------------------------------- -assign cpu_rst_n = reg_0[0]; -assign spi_rst_n = reg_0[1]; -assign sdram_rst_n = reg_0[2]; -assign cfg_sdram_clk_div = reg_0[3]; +assign cpu_rst_n = reg_0[0]; +assign spi_rst_n = reg_0[1]; +assign sdram_rst_n = reg_0[2]; +// SDRAM Clock source & div selection +wire cfg_sdram_clk_src_sel = reg_0[4]; +wire cfg_sdram_clk_div = reg_0[5]; +wire [1:0] cfg_sdram_clk_ratio = reg_0[7:6]; +// Core Clock source & div selection +wire cfg_cpu_clk_src_sel = reg_0[8]; +wire cfg_cpu_clk_div = reg_0[9]; +wire [1:0] cfg_cpu_clk_ratio = reg_0[11:10]; + +// RTC Clock source & div selection +wire cfg_rtc_clk_src_sel = reg_0[12]; +wire cfg_rtc_clk_div = reg_0[13]; +wire [1:0] cfg_rtc_clk_ratio = reg_0[15:14]; generic_register #(8,0 ) u_reg0_be0 ( .we ({8{sw_wr_en_0 & @@ -429,7 +443,7 @@ .data_out (reg_3[15:8] ) ); generic_register #(4,0 ) u_reg3_be2 ( - .we ({1{sw_wr_en_3 & + .we ({4{sw_wr_en_3 & wr_be[2] }} ), .data_in (sw_reg_wdata[19:16] ), .reset_n (reset_n ), @@ -1030,29 +1044,72 @@ .clk (mclk ), //List of Outs - .data_out (reg_15[31:24] ) + .data_out (reg_15[31:24] ) ); //---------------------------------- -// Generate SDRAM Div-2 Clock +// Generate SDRAM Clock Generation //---------------------------------- -wire sdram_clk_div2; +wire sdram_clk_div; +wire sdram_ref_clk; -assign sdram_clk = (cfg_sdram_clk_div) ? sdram_clk_div2 : mclk; +assign sdram_ref_clk = (cfg_sdram_clk_src_sel) ? user_clock2 : mclk; + + + +assign sdram_clk = (cfg_sdram_clk_div) ? sdram_clk_div : sdram_ref_clk; clk_ctl #(1) u_sdramclk ( // Outputs - .clk_o (sdram_clk_div2), + .clk_o (sdram_clk_div ), // Inputs - .mclk (mclk), - .reset_n (reset_n), - .clk_div_ratio (2'b00) + .mclk (sdram_ref_clk ), + .reset_n (reset_n ), + .clk_div_ratio (cfg_sdram_clk_ratio) ); +//---------------------------------- +// Generate CORE Clock Generation +//---------------------------------- +wire cpu_clk_div; +wire cpu_ref_clk; + +assign cpu_ref_clk = (cfg_cpu_clk_src_sel) ? user_clock2 : mclk; +assign cpu_clk = (cfg_cpu_clk_div) ? cpu_clk_div : cpu_ref_clk; + + +clk_ctl #(1) u_cpuclk ( + // Outputs + .clk_o (cpu_clk_div ), + // Inputs + .mclk (cpu_ref_clk ), + .reset_n (reset_n ), + .clk_div_ratio (cfg_cpu_clk_ratio) + ); + +//---------------------------------- +// Generate RTC Clock Generation +//---------------------------------- +wire rtc_clk_div; +wire rtc_ref_clk; + +assign rtc_ref_clk = (cfg_rtc_clk_src_sel) ? user_clock2 : mclk; +assign rtc_clk = (cfg_rtc_clk_div) ? rtc_clk_div : rtc_ref_clk; + + +clk_ctl #(1) u_rtcclk ( + // Outputs + .clk_o (rtc_clk_div ), + // Inputs + .mclk (rtc_ref_clk ), + .reset_n (reset_n ), + .clk_div_ratio (cfg_rtc_clk_ratio) + ); + endmodule
diff --git a/verilog/rtl/lib/wb_crossbar.v b/verilog/rtl/lib/wb_crossbar.v deleted file mode 100644 index 76b9981..0000000 --- a/verilog/rtl/lib/wb_crossbar.v +++ /dev/null
@@ -1,398 +0,0 @@ -////////////////////////////////////////////////////////////////////// -//// //// -//// yifive common library Module //// -//// //// -//// This file is part of the yifive cores project //// -//// http://www.opencores.org/cores/yifive/ //// -//// //// -//// Description //// -//// This module does the Wishone crossbar network //// -//// //// -//// To Do: //// -//// nothing //// -//// //// -//// Author(s): //// -//// - Dinesh Annayya, dinesha@opencores.org //// -//// //// -////////////////////////////////////////////////////////////////////// -//// Revision : //// -//// v0: Nov 26, 2016, Dinesh A //// -//// This files copied from my open core //// -//// turbo8051 project //// -////////////////////////////////////////////////////////////////////// -//// //// -//// Copyright (C) 2000 Authors and OPENCORES.ORG //// -//// //// -//// This source file may be used and distributed without //// -//// restriction provided that this copyright statement is not //// -//// removed from the file and that any derivative work contains //// -//// the original copyright notice and the associated disclaimer. //// -//// //// -//// This source file is free software; you can redistribute it //// -//// and/or modify it under the terms of the GNU Lesser General //// -//// Public License as published by the Free Software Foundation; //// -//// either version 2.1 of the License, or (at your option) any //// -//// later version. //// -//// //// -//// This source is distributed in the hope that it will be //// -//// useful, but WITHOUT ANY WARRANTY; without even the implied //// -//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// -//// PURPOSE. See the GNU Lesser General Public License for more //// -//// details. //// -//// //// -//// You should have received a copy of the GNU Lesser General //// -//// Public License along with this source; if not, download it //// -//// from http://www.opencores.org/lgpl.shtml //// -//// //// -////////////////////////////////////////////////////////////////////// - -/********************************************** - Wish-bone cross bar M-Master By S-Slave -**********************************************/ - -module wb_crossbar ( - - rst_n , - clk , - - - // Master Interface Signal - wbd_taddr_master , - wbd_din_master , - wbd_dout_master , - wbd_adr_master , - wbd_be_master , - wbd_we_master , - wbd_ack_master , - wbd_stb_master , - wbd_cyc_master , - wbd_err_master , - wbd_rty_master , - - // Slave Interface Signal - wbd_din_slave , - wbd_dout_slave , - wbd_adr_slave , - wbd_be_slave , - wbd_we_slave , - wbd_ack_slave , - wbd_stb_slave , - wbd_cyc_slave , - wbd_err_slave , - wbd_rty_slave - ); - -parameter WB_SLAVE = 4 ; -parameter WB_MASTER = 4 ; - -parameter D_WD = 16; // Data Width -parameter BE_WD = 2; // Byte Enable -parameter ADR_WD = 28; // Address Width -parameter TAR_WD = 4; // Target Width - -input clk; // CLK_I The clock input [CLK_I] coordinates all activities - // for the internal logic within the WISHBONE interconnect. - // All WISHBONE output signals are registered at the - // rising edge of [CLK_I]. - // All WISHBONE input signals must be stable before the - // rising edge of [CLK_I]. -input rst_n; // RST_I The reset input [RST_I] forces the WISHBONE interface - // to restart. Furthermore, all internal self-starting state - // machines will be forced into an initial state. - -input [(WB_MASTER *TAR_WD)-1:0] wbd_taddr_master; // target address from master -input [WB_MASTER-1:0] wbd_stb_master; - // STB_O The strobe output [STB_O] indicates a valid data - // transfer cycle. It is used to qualify various other signals - // on the interface such as [SEL_O(7..0)]. The SLAVE must - // assert either the [ACK_I], [ERR_I] or [RTY_I] signals in - // response to every assertion of the [STB_O] signal. -output [WB_SLAVE-1:0] wbd_stb_slave; - // STB_O The strobe output [STB_O] indicates a valid data - // transfer cycle. It is used to qualify various other signals - // on the interface such as [SEL_O(7..0)]. The SLAVE must - // assert either the [ACK_I], [ERR_I] or [RTY_I] signals in - // response to every assertion of the [STB_O] signal. - -input [WB_MASTER-1:0] wbd_we_master; - // WE_O The write enable output [WE_O] indicates whether the - // current local bus cycle is a READ or WRITE cycle. The - // signal is negated during READ cycles, and is asserted - // during WRITE cycles. -output [WB_SLAVE-1:0] wbd_we_slave; - // WE_O The write enable output [WE_O] indicates whether the - // current local bus cycle is a READ or WRITE cycle. The - // signal is negated during READ cycles, and is asserted - // during WRITE cycles. - -output [WB_MASTER-1:0] wbd_ack_master; - // The acknowledge input [ACK_I], when asserted, - // indicates the termination of a normal bus cycle. - // Also see the [ERR_I] and [RTY_I] signal descriptions. -input [WB_SLAVE-1:0] wbd_ack_slave; - // The acknowledge input [ACK_I], when asserted, - // indicates the termination of a normal bus cycle. - // Also see the [ERR_I] and [RTY_I] signal descriptions. - -input [(WB_MASTER *ADR_WD)-1:0] wbd_adr_master; - // The address output array [ADR_O(63..0)] is used - // to pass a binary address, with the most significant - // address bit at the higher numbered end of the signal array. - // The lower array boundary is specific to the data port size. - // The higher array boundary is core-specific. - // In some cases (such as FIFO interfaces) - // the array may not be present on the interface. - -output [(WB_SLAVE *ADR_WD)-1:0] wbd_adr_slave; - // The address output array [ADR_O(63..0)] is used - // to pass a binary address, with the most significant - // address bit at the higher numbered end of the signal array. - // The lower array boundary is specific to the data port size. - // The higher array boundary is core-specific. - // In some cases (such as FIFO interfaces) - // the array may not be present on the interface. - -input [(WB_MASTER * BE_WD)-1:0] wbd_be_master; // Byte Enable - // SEL_O(7..0) The select output array [SEL_O(7..0)] indicates - // where valid data is expected on the [DAT_I(63..0)] signal - // array during READ cycles, and where it is placed on the - // [DAT_O(63..0)] signal array during WRITE cycles. - // Also see the [DAT_I(63..0)], [DAT_O(63..0)] and [STB_O] - // signal descriptions. -output [(WB_SLAVE * BE_WD)-1:0] wbd_be_slave; // Byte Enable - // SEL_O(7..0) The select output array [SEL_O(7..0)] indicates - // where valid data is expected on the [DAT_I(63..0)] signal - // array during READ cycles, and where it is placed on the - // [DAT_O(63..0)] signal array during WRITE cycles. - // Also see the [DAT_I(63..0)], [DAT_O(63..0)] and [STB_O] - // signal descriptions. - -input [WB_MASTER -1:0] wbd_cyc_master; - // CYC_O The cycle output [CYC_O], when asserted, - // indicates that a valid bus cycle is in progress. - // The signal is asserted for the duration of all bus cycles. - // For example, during a BLOCK transfer cycle there can be - // multiple data transfers. The [CYC_O] signal is asserted - // during the first data transfer, and remains asserted - // until the last data transfer. The [CYC_O] signal is useful - // for interfaces with multi-port interfaces - // (such as dual port memories). In these cases, - // the [CYC_O] signal requests use of a common bus from an - // arbiter. Once the arbiter grants the bus to the MASTER, - // it is held until [CYC_O] is negated. -output [WB_SLAVE -1:0] wbd_cyc_slave; - // CYC_O The cycle output [CYC_O], when asserted, - // indicates that a valid bus cycle is in progress. - // The signal is asserted for the duration of all bus cycles. - // For example, during a BLOCK transfer cycle there can be - // multiple data transfers. The [CYC_O] signal is asserted - // during the first data transfer, and remains asserted - // until the last data transfer. The [CYC_O] signal is useful - // for interfaces with multi-port interfaces - // (such as dual port memories). In these cases, - // the [CYC_O] signal requests use of a common bus from an - // arbiter. Once the arbiter grants the bus to the MASTER, - // it is held until [CYC_O] is negated. - -input [(WB_MASTER * D_WD)-1:0] wbd_din_master; - // DAT_I(63..0) The data input array [DAT_I(63..0)] is - // used to pass binary data. The array boundaries are - // determined by the port size. Also see the [DAT_O(63..0)] - // and [SEL_O(7..0)] signal descriptions. - -output [(WB_SLAVE * D_WD)-1:0] wbd_din_slave; - // DAT_I(63..0) The data input array [DAT_I(63..0)] is - // used to pass binary data. The array boundaries are - // determined by the port size. Also see the [DAT_O(63..0)] - // and [SEL_O(7..0)] signal descriptions. - -output [(WB_MASTER * D_WD)-1:0] wbd_dout_master; - // DAT_O(63..0) The data output array [DAT_O(63..0)] is - // used to pass binary data. The array boundaries are - // determined by the port size. Also see the [DAT_I(63..0)] - // and [SEL_O(7..0)] signal descriptions. -input [(WB_SLAVE * D_WD)-1:0] wbd_dout_slave; - // DAT_O(63..0) The data output array [DAT_O(63..0)] is - // used to pass binary data. The array boundaries are - // determined by the port size. Also see the [DAT_I(63..0)] - // and [SEL_O(7..0)] signal descriptions. - -output [WB_MASTER -1:0] wbd_err_master; - // ERR_I The error input [ERR_I] indicates an abnormal - // cycle termination. The source of the error, and the - // response generated by the MASTER is defined by the IP core - // supplier in the WISHBONE DATASHEET. Also see the [ACK_I] - // and [RTY_I] signal descriptions. -input [WB_SLAVE -1:0] wbd_err_slave; - // ERR_I The error input [ERR_I] indicates an abnormal - // cycle termination. The source of the error, and the - // response generated by the MASTER is defined by the IP core - // supplier in the WISHBONE DATASHEET. Also see the [ACK_I] - // and [RTY_I] signal descriptions. - -output [WB_MASTER -1:0] wbd_rty_master; - // RTY_I The retry input [RTY_I] indicates that the indicates - // that the interface is not ready to accept or send data, and - // that the cycle should be retried. When and how the cycle is - // retried is defined by the IP core supplier in the WISHBONE - // DATASHEET. Also see the [ERR_I] and [RTY_I] signal - // descriptions. -input [WB_SLAVE -1:0] wbd_rty_slave; - // RTY_I The retry input [RTY_I] indicates that the indicates - // that the interface is not ready to accept or send data, and - // that the cycle should be retried. When and how the cycle is - // retried is defined by the IP core supplier in the WISHBONE - // DATASHEET. Also see the [ERR_I] and [RTY_I] signal - // descriptions. - - -reg [WB_MASTER-1:0] wbd_ack_master; -reg [WB_MASTER-1:0] wbd_err_master; -reg [WB_MASTER-1:0] wbd_rty_master; - - -reg [WB_MASTER-1:0] master_busy; // master busy flag -reg [WB_SLAVE-1:0] slave_busy; // slave busy flag -reg [TAR_WD -1:0] master_mx_id[WB_MASTER-1:0]; -reg [TAR_WD -1:0] slave_mx_id [WB_SLAVE-1:0]; - -wire [TAR_WD-1:0] wbd_taddr_master_t[WB_MASTER-1:0]; // target address from master -wire [D_WD-1:0] wbd_din_master_t[WB_MASTER-1:0]; // target address from master -reg [D_WD-1:0] wbd_dout_master_t[WB_MASTER-1:0]; // target address from master -wire [ADR_WD-1:0] wbd_adr_master_t[WB_MASTER-1:0]; // target address from master -wire [BE_WD-1:0] wbd_be_master_t[WB_MASTER-1:0]; // target address from master - - -reg [WB_SLAVE-1:0] wbd_stb_slave; -reg [WB_SLAVE-1:0] wbd_we_slave; -reg [WB_SLAVE-1:0] wbd_cyc_slave; -wire [D_WD-1:0] wbd_dout_slave_t[WB_SLAVE-1:0]; // target data towards master - - -reg [D_WD-1:0] wbd_din_slave_t[WB_SLAVE-1:0]; // target address from master -reg [ADR_WD-1:0] wbd_adr_slave_t[WB_SLAVE-1:0]; // target address from master -reg [BE_WD-1:0] wbd_be_slave_t[WB_SLAVE-1:0]; // target address from master - -integer i,k,l,n; - - -/********************************************************** - Re-Arraging the array in seperate two dimensional information -***********************************************************/ - -genvar j,m; -generate - - // Connect the Master Mux - for(j=0; j < WB_MASTER ; j = j + 1) begin : master_expand - assign wbd_taddr_master_t[j] = wbd_taddr_master[((j+1)*TAR_WD)-1:j * TAR_WD]; - assign wbd_din_master_t[j] = wbd_din_master[((j+1)*D_WD)-1:j * D_WD]; - assign wbd_adr_master_t[j] = wbd_adr_master[((j+1)*ADR_WD)-1:j * ADR_WD]; - assign wbd_be_master_t[j] = wbd_be_master[((j+1)*BE_WD)-1:j * BE_WD]; - - assign wbd_dout_master[((j+1)*D_WD)-1:j * D_WD] = wbd_dout_master_t[j]; - end - - // Connect the Slave Mux - for(m=0; m < WB_SLAVE ; m = m + 1) begin : slave_expand - assign wbd_din_slave[((m+1)*D_WD)-1:m * D_WD] = wbd_din_slave_t[m]; - assign wbd_adr_slave[((m+1)*ADR_WD)-1:m * ADR_WD] = wbd_adr_slave_t[m]; - assign wbd_be_slave[((m+1)*BE_WD)-1:m * BE_WD] = wbd_be_slave_t[m]; - - assign wbd_dout_slave_t[m] = wbd_dout_slave[((m+1)*D_WD)-1:m * D_WD]; - - end -endgenerate - -always @* begin - for(k = 0; k < WB_MASTER; k = k + 1) begin - if(master_busy[k] == 1) begin - wbd_dout_master_t[k] = wbd_dout_slave_t[master_mx_id[k]]; - wbd_ack_master[k] = wbd_ack_slave[master_mx_id[k]]; - wbd_err_master[k] = wbd_err_slave[master_mx_id[k]]; - wbd_rty_master[k] = wbd_rty_slave[master_mx_id[k]]; - end else begin - wbd_dout_master_t[k] = 0; - wbd_ack_master[k] = 0; - wbd_err_master[k] = 0; - wbd_rty_master[k] = 0; - end - end - for(l = 0; l < WB_SLAVE; l = l + 1) begin - if(slave_busy[l] == 1) begin - wbd_din_slave_t[l] = wbd_din_master_t[slave_mx_id[l]]; - wbd_adr_slave_t[l] = wbd_adr_master_t[slave_mx_id[l]]; - wbd_be_slave_t[l] = wbd_be_master_t[slave_mx_id[l]]; - wbd_stb_slave[l] = wbd_stb_master[slave_mx_id[l]]; - wbd_we_slave[l] = wbd_we_master[slave_mx_id[l]]; - wbd_cyc_slave[l] = wbd_cyc_master[slave_mx_id[l]]; - end else begin - wbd_din_slave_t[l] = 0; - wbd_adr_slave_t[l] = 0; - wbd_be_slave_t[l] = 0; - wbd_stb_slave[l] = 0; - wbd_we_slave[l] = 0; - wbd_cyc_slave[l] = 0; - end - end -end - -/******************************************************* - Parsing through the master and deciding on mux connectio - Step-1: analysis the master from 0 to total master - Step-2: If the previously master is not busy, - Then check for any new request from the master and - check corresponding slave is free or not. If there is - master request and requesting slave is free. - Then set the master max id to slave id & - requesting slave to master number & set the master - and slave busy flag - Step-3: If the previous state of master is busy and bus-cycle - is de-asserted, then reset the master and corresponding - slave busy flag - -*********************************************************/ - -always @(negedge rst_n or posedge clk) begin - if(rst_n == 0) begin - master_busy <= 0; - slave_busy <= 0; - end else begin - for(i = 0; i < WB_MASTER; i = i + 1) begin - if(master_busy[i] == 0) begin - if(wbd_stb_master[i] & slave_busy[wbd_taddr_master_t[i]] == 0) begin - $display("Locking Master Id: %d for tar_master: %d, Total Master: %x ", i, wbd_taddr_master_t[i], wbd_taddr_master); - slave_busy[wbd_taddr_master_t[i]] = 1; - master_busy[i] = 1; - end - end else if(wbd_cyc_master[i] == 0) begin - master_busy[i] <= 0; - slave_busy[wbd_taddr_master_t[i]] <= 0; - end - end - end -end - -// Seperated non resetable two dimensional reg -always @(posedge clk) begin - for(n = 0; n < WB_MASTER; n = n + 1) begin - if(master_busy[n] == 0) begin - if(wbd_stb_master[n] & slave_busy[wbd_taddr_master_t[n]] == 0) begin - master_mx_id[n] <= wbd_taddr_master_t[n]; - slave_mx_id [wbd_taddr_master_t[n]] <= n; - // synopsys translate_off - $display("%m:%t: Locking Master : %d with Slave : %d",$time,i,wbd_taddr_master_t[n]); - // synopsys translate_on - end - end else if(wbd_cyc_master[n] == 0) begin - if(master_busy[n] == 1) begin - // synopsys translate_off - $display("%m:%t: Releasing Master : %d with Slave : %d",$time,i,wbd_taddr_master_t[n]); - // synopsys translate_on - end - end - end -end - - -endmodule
diff --git a/verilog/rtl/lib/wb_stagging.sv b/verilog/rtl/lib/wb_stagging.sv new file mode 100644 index 0000000..7c1330a --- /dev/null +++ b/verilog/rtl/lib/wb_stagging.sv
@@ -0,0 +1,148 @@ +//---------------------------------------------------------------------- +// This logic create a holding register for Wishbone interface. +// This is usefull to break timing issue at interconnect +// +// Limitation: Due to stagging FF, Continous Burst of Wishbone will have one +// cycle break between each transaction +//---------------------------------------------------------------------- +////////////////////////////////////////////////////////////////////// +//// //// +//// Wishbone Stagging FF //// +//// //// +//// This file is part of the YIFive cores project //// +//// http://www.opencores.org/cores/yifive/ //// +//// //// +//// Description //// +//// This logic create a holding FF for Wishbone interface. //// +//// This is usefull to break timing issue at interconnect //// +//// //// +//// Limitation: Due to stagging FF, Continous Burst of //// +//// Wishbone will have one cycle break between each transaction //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +//// Revision : //// +//// 0.1 - 12th June 2021, Dinesh A //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + + +module wb_stagging ( + input logic clk_i, + input logic rst_n, + // WishBone Input master I/P + input logic [31:0] m_wbd_dat_i, + input logic [31:0] m_wbd_adr_i, + input logic [3:0] m_wbd_sel_i, + input logic m_wbd_we_i, + input logic m_wbd_cyc_i, + input logic m_wbd_stb_i, + output logic [31:0] m_wbd_dat_o, + output logic m_wbd_ack_o, + output logic m_wbd_err_o, + + // Slave Interface + input logic [31:0] s_wbd_dat_i, + input logic s_wbd_ack_i, + input logic s_wbd_err_i, + output logic [31:0] s_wbd_dat_o, + output logic [31:0] s_wbd_adr_o, + output logic [3:0] s_wbd_sel_o, + output logic s_wbd_we_o, + output logic s_wbd_cyc_o, + output logic s_wbd_stb_o + +); + +logic holding_busy ; // Indicate Stagging for Free or not +logic [31:0] m_wbd_dat_i_ff ; // Flopped vesion of m_wbd_dat_i +logic [31:0] m_wbd_adr_i_ff ; // Flopped vesion of m_wbd_adr_i +logic [3:0] m_wbd_sel_i_ff ; // Flopped vesion of m_wbd_sel_i +logic m_wbd_we_i_ff ; // Flopped vesion of m_wbd_we_i +logic m_wbd_cyc_i_ff ; // Flopped vesion of m_wbd_cyc_i +logic m_wbd_stb_i_ff ; // Flopped vesion of m_wbd_stb_i +logic [31:0] s_wbd_dat_i_ff ; // Flopped vesion of s_wbd_dat_i +logic s_wbd_ack_i_ff ; // Flopped vesion of s_wbd_ack_i +logic s_wbd_err_i_ff ; // Flopped vesion of s_wbd_err_i + + +assign s_wbd_dat_o = m_wbd_dat_i_ff; +assign s_wbd_adr_o = m_wbd_adr_i_ff; +assign s_wbd_sel_o = m_wbd_sel_i_ff; +assign s_wbd_we_o = m_wbd_we_i_ff; +assign s_wbd_cyc_o = m_wbd_cyc_i_ff; +assign s_wbd_stb_o = m_wbd_stb_i_ff; + +assign m_wbd_dat_o = s_wbd_dat_i_ff; +assign m_wbd_ack_o = s_wbd_ack_i_ff; +assign m_wbd_err_o = s_wbd_err_i_ff; + +always @(negedge rst_n or posedge clk_i) +begin + if(rst_n == 1'b0) begin + holding_busy <= 1'b0; + m_wbd_dat_i_ff <= 'h0; + m_wbd_adr_i_ff <= 'h0; + m_wbd_sel_i_ff <= 'h0; + m_wbd_we_i_ff <= 'h0; + m_wbd_cyc_i_ff <= 'h0; + m_wbd_stb_i_ff <= 'h0; + s_wbd_dat_i_ff <= 'h0; + s_wbd_ack_i_ff <= 'h0; + s_wbd_err_i_ff <= 'h0; + end begin + s_wbd_dat_i_ff <= s_wbd_dat_i; + s_wbd_ack_i_ff <= s_wbd_ack_i; + s_wbd_err_i_ff <= s_wbd_err_i; + if(m_wbd_stb_i && holding_busy == 0 && m_wbd_ack_o == 0) begin + holding_busy <= 1'b1; + m_wbd_dat_i_ff <= m_wbd_dat_i; + m_wbd_adr_i_ff <= m_wbd_adr_i; + m_wbd_sel_i_ff <= m_wbd_sel_i; + m_wbd_we_i_ff <= m_wbd_we_i; + m_wbd_cyc_i_ff <= m_wbd_cyc_i; + m_wbd_stb_i_ff <= m_wbd_stb_i; + end else if (holding_busy && s_wbd_ack_i) begin + holding_busy <= 1'b0; + m_wbd_dat_i_ff <= 'h0; + m_wbd_adr_i_ff <= 'h0; + m_wbd_sel_i_ff <= 'h0; + m_wbd_we_i_ff <= 'h0; + m_wbd_cyc_i_ff <= 'h0; + m_wbd_stb_i_ff <= 'h0; + end + end +end + + +endmodule +
diff --git a/verilog/rtl/spi_master/src/spim_clkgen.sv b/verilog/rtl/spi_master/src/spim_clkgen.sv index 9c825a6..8c9fa83 100644 --- a/verilog/rtl/spi_master/src/spim_clkgen.sv +++ b/verilog/rtl/spi_master/src/spim_clkgen.sv
@@ -58,16 +58,16 @@ input logic clk, input logic rstn, input logic en, - input logic [7:0] cfg_sck_period, + input logic [5:0] cfg_sck_period, output logic spi_clk, output logic spi_fall, output logic spi_rise ); - logic [7:0] sck_half_period; - logic [7:0] clk_cnt; + logic [5:0] sck_half_period; + logic [5:0] clk_cnt; - assign sck_half_period = {1'b0, cfg_sck_period[7:1]}; + assign sck_half_period = {1'b0, cfg_sck_period[5:1]}; // The first transition on the sck_toggle happens one SCK period // after en is asserted
diff --git a/verilog/rtl/spi_master/src/spim_ctrl.sv b/verilog/rtl/spi_master/src/spim_ctrl.sv index 8ce6524..5ae41ad 100644 --- a/verilog/rtl/spi_master/src/spim_ctrl.sv +++ b/verilog/rtl/spi_master/src/spim_ctrl.sv
@@ -49,7 +49,7 @@ input logic rstn, output logic eot, - input logic [7:0] spi_clk_div, + input logic [5:0] spi_clk_div, output logic [8:0] spi_status,
diff --git a/verilog/rtl/syntacore/scr1/src/top/scr1_dmem_wb.sv b/verilog/rtl/syntacore/scr1/src/top/scr1_dmem_wb.sv index 85a0c5c..b9e893a 100644 --- a/verilog/rtl/syntacore/scr1/src/top/scr1_dmem_wb.sv +++ b/verilog/rtl/syntacore/scr1/src/top/scr1_dmem_wb.sv
@@ -21,6 +21,9 @@ //// On power up, wishbone output are unkown as it //// //// driven from fifo output. To avoid unknown //// //// propgation, we are driving 'h0 when fifo empty //// +//// v2: June 18, 2021, Dinesh A //// +//// core and wishbone is made async and async fifo //// +//// added to take care of domain cross-over //// //// //// ////////////////////////////////////////////////////////////////////// //// //// @@ -60,8 +63,8 @@ module scr1_dmem_wb ( // Control Signals - input logic rst_n, - input logic clk, + input logic core_rst_n, // core reset + input logic core_clk, // Core clock // Core Interface output logic dmem_req_ack, @@ -74,6 +77,8 @@ output logic [1:0] dmem_resp, // WB Interface + input logic wb_rst_n, // wishbone reset + input logic wb_clk, // wishbone clock output logic wbd_stb_o, // strobe/request output logic [SCR1_WB_WIDTH-1:0] wbd_adr_o, // address output logic wbd_we_o, // write @@ -88,31 +93,19 @@ //------------------------------------------------------------------------------- // Local Parameters //------------------------------------------------------------------------------- -`ifndef SCR1_DMEM_WB_OUT_BP -localparam SCR1_FIFO_WIDTH = 2; -localparam SCR1_FIFO_CNT_WIDTH = 2; -`endif // SCR1_DMEM_WB_OUT_BP //------------------------------------------------------------------------------- // Local type declaration //------------------------------------------------------------------------------- -typedef enum logic { - SCR1_FSM_ADDR = 1'b0, - SCR1_FSM_DATA = 1'b1, - SCR1_FSM_ERR = 1'bx -} type_scr1_fsm_e; typedef struct packed { + logic [3:0] hbel; logic hwrite; logic [2:0] hwidth; logic [SCR1_WB_WIDTH-1:0] haddr; logic [SCR1_WB_WIDTH-1:0] hwdata; } type_scr1_req_fifo_s; -typedef struct packed { - logic [2:0] hwidth; - logic [1:0] haddr; -} type_scr1_data_fifo_s; typedef struct packed { logic hresp; @@ -238,85 +231,18 @@ //------------------------------------------------------------------------------- logic req_fifo_rd; logic req_fifo_wr; -logic req_fifo_up; -`ifdef SCR1_DMEM_WB_OUT_BP -type_scr1_req_fifo_s req_fifo_new; -type_scr1_req_fifo_s req_fifo_r; -type_scr1_req_fifo_s [0:0] req_fifo; -`else // SCR1_DMEM_WB_OUT_BP -type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1] req_fifo; -type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1] req_fifo_new; -logic [SCR1_FIFO_CNT_WIDTH-1:0] req_fifo_cnt; -logic [SCR1_FIFO_CNT_WIDTH-1:0] req_fifo_cnt_new; -`endif // SCR1_DMEM_WB_OUT_BP logic req_fifo_empty; logic req_fifo_full; -type_scr1_data_fifo_s data_fifo; -type_scr1_resp_fifo_s resp_fifo; -logic resp_fifo_hready; + +logic resp_fifo_rd; +logic resp_fifo_empty; +logic resp_fifo_full; + //------------------------------------------------------------------------------- -// Interface to Core +// REQ_FIFO (CORE to WB) //------------------------------------------------------------------------------- -assign dmem_req_ack = ~req_fifo_full; -assign req_fifo_wr = ~req_fifo_full & dmem_req; - -assign dmem_rdata = (resp_fifo_hready) ? scr1_conv_wb2mem_rdata(resp_fifo.hwidth, resp_fifo.haddr, resp_fifo.hrdata) : 'h0; - -assign dmem_resp = (resp_fifo_hready) - ? (resp_fifo.hresp == 1'b1) - ? SCR1_MEM_RESP_RDY_OK - : SCR1_MEM_RESP_RDY_ER - : SCR1_MEM_RESP_NOTRDY ; - -//------------------------------------------------------------------------------- -// REQ_FIFO -//------------------------------------------------------------------------------- -`ifdef SCR1_DMEM_WB_OUT_BP -always_ff @(negedge rst_n, posedge clk) begin - if (~rst_n) begin - req_fifo_full <= 1'b0; - end else begin - if (~req_fifo_full) begin - req_fifo_full <= dmem_req & ~req_fifo_rd; - end else begin - req_fifo_full <= ~req_fifo_rd; - end - end -end -assign req_fifo_empty = ~(req_fifo_full | dmem_req); - -assign req_fifo_up = ~req_fifo_rd & req_fifo_wr; -always_ff @(posedge clk) begin - if (req_fifo_up) begin - req_fifo_r <= req_fifo_new; - end -end - -assign req_fifo_new.hwrite = dmem_req ? (dmem_cmd == SCR1_MEM_CMD_WR) : 1'b0; -assign req_fifo_new.hwidth = dmem_req ? scr1_conv_mem2wb_width(dmem_width) : '0; -assign req_fifo_new.haddr = dmem_req ? dmem_addr : '0; -assign req_fifo_new.hwdata = (dmem_req & (dmem_cmd == SCR1_MEM_CMD_WR)) - ? scr1_conv_mem2wb_wdata(dmem_addr[1:0], dmem_width, dmem_wdata) - : '0; -assign req_fifo[0] = (req_fifo_full) ? req_fifo_r: req_fifo_new; - -//------------------------------------------------------------------------------- -// Register Data from response path - Used by Read path logic -//------------------------------------------------------------------------------- -always_ff @(posedge clk) begin - if (wbd_ack_i) begin - if (~req_fifo_empty) begin - data_fifo.hwidth <= req_fifo[0].hwidth; - data_fifo.haddr <= req_fifo[0].haddr[1:0]; - end - end -end - -`else // SCR1_DMEM_WB_OUT_BP - - wire hwrite_in = (dmem_cmd == SCR1_MEM_CMD_WR); wire [2:0] hwidth_in = scr1_conv_mem2wb_width(dmem_width); wire [SCR1_WB_WIDTH-1:0] haddr_in = dmem_addr; @@ -339,47 +265,46 @@ end -wire [SCR1_WB_WIDTH+SCR1_WB_WIDTH+3+4:0] req_fifo_din = {hbel_in,hwrite_in,hwidth_in,haddr_in,hwdata_in}; -wire [SCR1_WB_WIDTH+SCR1_WB_WIDTH+3+4:0] req_fifo_dout; +//------------------------------------------------------------------------------- +// REQ_FIFO (WB to CORE) +//------------------------------------------------------------------------------- +type_scr1_req_fifo_s req_fifo_din; +type_scr1_req_fifo_s req_fifo_dout; - sync_fifo #( + +assign dmem_req_ack = ~req_fifo_full; +assign req_fifo_wr = ~req_fifo_full & dmem_req; + +//pack data in +assign req_fifo_din.hbel = hbel_in; +assign req_fifo_din.hwrite = hwrite_in; +assign req_fifo_din.hwidth = hwidth_in; +assign req_fifo_din.haddr = haddr_in; +assign req_fifo_din.hwdata = hwdata_in; + + + async_fifo #( .W(SCR1_WB_WIDTH+SCR1_WB_WIDTH+3+1+4), // Data Width - .D(2) // FIFO DEPTH + .DP(4), // FIFO DEPTH + .WR_FAST(1), // We need FF'ed Full + .RD_FAST(1) // We need FF'ed Empty ) u_req_fifo( + // Writc Clock + .wr_clk (core_clk ), + .wr_reset_n (core_rst_n ), + .wr_en (req_fifo_wr ), + .wr_data (req_fifo_din ), + .full (req_fifo_full ), + .afull ( ), - .rd_data (req_fifo_dout ), - - .reset_n (rst_n ), - .clk (clk ), - .wr_en (req_fifo_wr ), // Write - .rd_en (req_fifo_rd ), // Read - .wr_data (req_fifo_din ), - .full (req_fifo_full ), - .empty (req_fifo_empty ) -); - -//------------------------------------------------------------------------------- -// Register Data from response path - Used by Read path logic -//------------------------------------------------------------------------------- -wire hwrite_out; -wire [2:0] hwidth_out; -wire [SCR1_WB_WIDTH-1:0] haddr_out; -wire [SCR1_WB_WIDTH-1:0] hwdata_out; -wire [3:0] hbel_out; - - -assign {hbel_out,hwrite_out,hwidth_out,haddr_out,hwdata_out} = req_fifo_dout; - -always_ff @(posedge clk) begin - if (wbd_ack_i) begin - if (~req_fifo_empty) begin - data_fifo.hwidth <= hwidth_out; - data_fifo.haddr <= haddr_out[1:0]; - end - end -end - -`endif // SCR1_DMEM_WB_OUT_BP + // RD Clock + .rd_clk (wb_clk ), + .rd_reset_n (wb_rst_n ), + .rd_en (req_fifo_rd ), + .empty (req_fifo_empty ), + .aempty ( ), + .rd_data (req_fifo_dout ) + ); always_comb begin @@ -390,64 +315,62 @@ end -//------------------------------------------------------------------------------- -// FIFO response -//------------------------------------------------------------------------------- -`ifdef SCR1_DMEM_WB_IN_BP - -assign resp_fifo_hready = wbd_ack_i; -assign resp_fifo.hresp = (wbd_err_i) ? 1'b0 : 1'b1; -assign resp_fifo.hwidth = data_fifo.hwidth; -assign resp_fifo.haddr = data_fifo.haddr; -assign resp_fifo.hrdata = wbd_dat_i; - -assign wbd_stb_o = ~req_fifo_empty; -assign wbd_adr_o = req_fifo[0].haddr; -assign wbd_we_o = req_fifo[0].hwrite; -assign wbd_dat_o = req_fifo[0].hwdata; - -always_comb begin - wbd_sel_o = 0; - case (req_fifo[0].hwidth) - SCR1_DSIZE_8B : begin - wbd_sel_o = 4'b0001 << req_fifo[0].haddr[1:0]; - end - SCR1_DSIZE_16B : begin - wbd_sel_o = 4'b0011 << req_fifo[0].haddr[1:0]; - end - SCR1_DSIZE_32B : begin - wbd_sel_o = 4'b1111; - end - endcase -end -`else // SCR1_DMEM_WB_IN_BP -always_ff @(negedge rst_n, posedge clk) begin - if (~rst_n) begin - resp_fifo_hready <= 1'b0; - end else begin - resp_fifo_hready <= wbd_ack_i ; - end -end - -always_ff @(posedge clk) begin - if (wbd_ack_i) begin - resp_fifo.hresp <= (wbd_err_i) ? 1'b0 : 1'b1; - resp_fifo.hwidth <= hwidth_out; - resp_fifo.haddr <= haddr_out[1:0]; - resp_fifo.hrdata <= (wbd_we_o) ? 'h0: wbd_dat_i; - end -end - - assign wbd_stb_o = ~req_fifo_empty; // To avoid unknown progating the design, driven zero when fifo is empty -assign wbd_adr_o = (req_fifo_empty) ? 'h0 : haddr_out; -assign wbd_we_o = (req_fifo_empty) ? 'h0 : hwrite_out; -assign wbd_dat_o = (req_fifo_empty) ? 'h0 : hwdata_out; -assign wbd_sel_o = (req_fifo_empty) ? 'h0 : hbel_out; +assign wbd_adr_o = (req_fifo_empty) ? 'h0 : req_fifo_dout.haddr; +assign wbd_we_o = (req_fifo_empty) ? 'h0 : req_fifo_dout.hwrite; +assign wbd_dat_o = (req_fifo_empty) ? 'h0 : req_fifo_dout.hwdata; +assign wbd_sel_o = (req_fifo_empty) ? 'h0 : req_fifo_dout.hbel; -`endif // SCR1_DMEM_WB_IN_BP + +//------------------------------------------------------------------------------- +// Response path - Used by Read path logic +//------------------------------------------------------------------------------- +type_scr1_resp_fifo_s resp_fifo_din; +type_scr1_resp_fifo_s resp_fifo_dout; + + +assign resp_fifo_din.hresp = (wbd_err_i) ? 1'b0 : 1'b1; +assign resp_fifo_din.hwidth = req_fifo_dout.hwidth; +assign resp_fifo_din.haddr = req_fifo_dout.haddr[1:0]; +assign resp_fifo_din.hrdata = (wbd_we_o) ? 'h0: wbd_dat_i; + + async_fifo #( + .W(SCR1_WB_WIDTH+2+3+1), // Data Width + .DP(4), // FIFO DEPTH + .WR_FAST(1), // We need FF'ed Full + .RD_FAST(1) // We need FF'ed Empty + ) u_res_fifo( + // Writc Clock + .wr_clk (wb_clk ), + .wr_reset_n (wb_rst_n ), + .wr_en (wbd_ack_i ), + .wr_data (resp_fifo_din ), + .full ( ), // Assmed FIFO will never be full as it's Response a Single Request + .afull ( ), + + // RD Clock + .rd_clk (core_clk ), + .rd_reset_n (core_rst_n ), + .rd_en (resp_fifo_rd ), + .empty (resp_fifo_empty ), + .aempty ( ), + .rd_data (resp_fifo_dout ) + ); + + + +assign resp_fifo_rd = !resp_fifo_empty; + +assign dmem_rdata = (resp_fifo_rd) ? scr1_conv_wb2mem_rdata(resp_fifo_dout.hwidth, resp_fifo_dout.haddr, resp_fifo_dout.hrdata) : 'h0; + +assign dmem_resp = (resp_fifo_rd) + ? (resp_fifo_dout.hresp == 1'b1) + ? SCR1_MEM_RESP_RDY_OK + : SCR1_MEM_RESP_RDY_ER + : SCR1_MEM_RESP_NOTRDY ; +
diff --git a/verilog/rtl/syntacore/scr1/src/top/scr1_imem_wb.sv b/verilog/rtl/syntacore/scr1/src/top/scr1_imem_wb.sv index d91c9e3..fb6c137 100644 --- a/verilog/rtl/syntacore/scr1/src/top/scr1_imem_wb.sv +++ b/verilog/rtl/syntacore/scr1/src/top/scr1_imem_wb.sv
@@ -21,6 +21,9 @@ //// On power up, wishbone output are unkown as it //// //// driven from fifo output. To avoid unknown //// //// propgation, we are driving 'h0 when fifo empty //// +//// v2: June 18, 2021, Dinesh A //// +//// core and wishbone is made async and async fifo //// +//// added to take care of domain cross-over //// //// //// ////////////////////////////////////////////////////////////////////// //// //// @@ -60,8 +63,8 @@ module scr1_imem_wb ( // Control Signals - input logic rst_n, - input logic clk, + input logic core_rst_n, // core reset + input logic core_clk, // Core clock // Core Interface output logic imem_req_ack, @@ -71,6 +74,8 @@ output logic [1:0] imem_resp, // WB Interface + input logic wb_rst_n, // wishbone reset + input logic wb_clk, // wishbone clock output logic wbd_stb_o, // strobe/request output logic [SCR1_WB_WIDTH-1:0] wbd_adr_o, // address output logic wbd_we_o, // write @@ -85,19 +90,10 @@ //------------------------------------------------------------------------------- // Local parameters declaration //------------------------------------------------------------------------------- -`ifndef SCR1_IMEM_WB_OUT_BP -localparam SCR1_FIFO_WIDTH = 2; -localparam SCR1_FIFO_CNT_WIDTH = $clog2(SCR1_FIFO_WIDTH+1); -`endif // SCR1_IMEM_WB_OUT_BP //------------------------------------------------------------------------------- // Local types declaration //------------------------------------------------------------------------------- -typedef enum logic { - SCR1_FSM_ADDR = 1'b0, - SCR1_FSM_DATA = 1'b1, - SCR1_FSM_ERR = 1'bx -} type_scr1_fsm_e; typedef struct packed { logic [SCR1_WB_WIDTH-1:0] haddr; @@ -111,86 +107,57 @@ //------------------------------------------------------------------------------- // Local signal declaration //------------------------------------------------------------------------------- -type_scr1_fsm_e fsm; + +//------------------------------------------------------------------------------- +// Request FIFO +// ------------------------------------------------------------------------------ logic req_fifo_rd; logic req_fifo_wr; -logic req_fifo_up; -`ifdef SCR1_IMEM_WB_OUT_BP -type_scr1_req_fifo_s req_fifo_r; -type_scr1_req_fifo_s [0:0] req_fifo; -`else // SCR1_IMEM_WB_OUT_BP -logic [SCR1_WB_WIDTH-1:0] req_fifo_dout; -`endif // SCR1_IMEM_WB_OUT_BP - logic req_fifo_empty; logic req_fifo_full; -type_scr1_resp_fifo_s resp_fifo; -logic resp_fifo_hready; -//------------------------------------------------------------------------------- -// Interface to Core -//------------------------------------------------------------------------------- -assign imem_req_ack = ~req_fifo_full; -assign req_fifo_wr = ~req_fifo_full & imem_req; +//----------------------------------------------------- +// Response FIFO (READ PATH +// ---------------------------------------------------- +logic resp_fifo_empty; +logic resp_fifo_rd; -assign imem_rdata = resp_fifo.hrdata; -assign imem_resp = (resp_fifo_hready) - ? (resp_fifo.hresp == 1'b1) - ? SCR1_MEM_RESP_RDY_OK - : SCR1_MEM_RESP_RDY_ER - : SCR1_MEM_RESP_NOTRDY; //------------------------------------------------------------------------------- // REQ_FIFO //------------------------------------------------------------------------------- -`ifdef SCR1_IMEM_WB_OUT_BP -always_ff @(negedge rst_n, posedge clk) begin - if (~rst_n) begin - req_fifo_full <= 1'b0; - end else begin - if (~req_fifo_full) begin - req_fifo_full <= imem_req & ~req_fifo_rd; - end else begin - req_fifo_full <= ~req_fifo_rd; - end - end -end -assign req_fifo_empty = ~(req_fifo_full | imem_req); +type_scr1_req_fifo_s req_fifo_din; +type_scr1_req_fifo_s req_fifo_dout; -assign req_fifo_up = ~req_fifo_rd & req_fifo_wr; -always_ff @(posedge clk) begin - if (req_fifo_up) begin - req_fifo_r.haddr <= imem_addr; - end -end +assign req_fifo_wr = ~req_fifo_full & imem_req; +assign imem_req_ack = ~req_fifo_full; -assign req_fifo[0] = (req_fifo_full) ? req_fifo_r : imem_addr; +assign req_fifo_din.haddr = imem_addr; -`else // SCR1_IMEM_WB_OUT_BP - - - sync_fifo #( + async_fifo #( .W(SCR1_WB_WIDTH), // Data Width - .D(2) // FIFO DEPTH + .DP(4), // FIFO DEPTH + .WR_FAST(1), // We need FF'ed Full + .RD_FAST(1) // We need FF'ed Empty ) u_req_fifo( + // Writc Clock + .wr_clk (core_clk ), + .wr_reset_n (core_rst_n ), + .wr_en (req_fifo_wr ), + .wr_data (req_fifo_din ), + .full (req_fifo_full ), + .afull ( ), - .rd_data (req_fifo_dout ), - - .reset_n (rst_n ), - .clk (clk ), - .wr_en (req_fifo_wr ), // Write - .rd_en (req_fifo_rd ), // Read - .wr_data (imem_addr ), - .full (req_fifo_full ), - .empty (req_fifo_empty ) -); - - - - -`endif // SCR1_IMEM_WB_OUT_BP + // RD Clock + .rd_clk (wb_clk ), + .rd_reset_n (wb_rst_n ), + .rd_en (req_fifo_rd ), + .empty (req_fifo_empty ), + .aempty ( ), + .rd_data (req_fifo_dout ) + ); always_comb begin @@ -200,44 +167,53 @@ end end -//------------------------------------------------------------------------------- -// FIFO response -//------------------------------------------------------------------------------- -`ifdef SCR1_IMEM_WB_IN_BP -assign resp_fifo_hready = wbd_ack_i; -assign resp_fifo.hresp = (wbd_err_i) ? 1'b0 : 1'b1; -assign resp_fifo.hrdata = wbd_dat_i; -assign wbd_stb_o = ~req_fifo_empty; -assign wbd_adr_o = req_fifo[0]; -assign wbd_we_o = 0; // Only Read supported -assign wbd_dat_o = 32'h0; // No Write -assign wbd_sel_o = 4'b1111; // Only Read allowed in imem i/f - - -`else // SCR1_IMEM_WB_IN_BP -always_ff @(negedge rst_n, posedge clk) begin - if (~rst_n) begin - resp_fifo_hready <= 1'b0; - end else begin - resp_fifo_hready <= wbd_ack_i ; - end -end - -always_ff @(posedge clk) begin - if (wbd_ack_i) begin - resp_fifo.hresp <= (wbd_err_i) ? 1'b0 : 1'b1; - resp_fifo.hrdata <= wbd_dat_i; - end -end - assign wbd_stb_o = ~req_fifo_empty; // On Power, to avoid unknow propgating the value -assign wbd_adr_o = (req_fifo_empty) ? 'h0 : req_fifo_dout; +assign wbd_adr_o = (req_fifo_empty) ? 'h0 : req_fifo_dout.haddr; assign wbd_we_o = 0; // Only Read supported assign wbd_dat_o = 32'h0; // No Write assign wbd_sel_o = 4'b1111; // Only Read allowed in imem i/f -`endif // SCR1_IMEM_WB_IN_BP +//------------------------------------------------------------------------------- +// Response path - Used by Read path logic +//------------------------------------------------------------------------------- +type_scr1_resp_fifo_s resp_fifo_din; +type_scr1_resp_fifo_s resp_fifo_dout; +assign resp_fifo_din.hresp = (wbd_err_i) ? 1'b0 : 1'b1; +assign resp_fifo_din.hrdata = wbd_dat_i; + + async_fifo #( + .W(SCR1_WB_WIDTH+1), // Data Width + .DP(4), // FIFO DEPTH + .WR_FAST(1), // We need FF'ed Full + .RD_FAST(1) // We need FF'ed Empty + ) u_res_fifo( + // Writc Clock + .wr_clk (wb_clk ), + .wr_reset_n (wb_rst_n ), + .wr_en (wbd_ack_i ), + .wr_data (resp_fifo_din ), + .full ( ), // Assmed FIFO will never be full as it's Response a Single Request + .afull ( ), + + // RD Clock + .rd_clk (core_clk ), + .rd_reset_n (core_rst_n ), + .rd_en (resp_fifo_rd ), + .empty (resp_fifo_empty ), + .aempty ( ), + .rd_data (resp_fifo_dout ) + ); + + +assign resp_fifo_rd = !resp_fifo_empty; +assign imem_rdata = resp_fifo_dout.hrdata; + +assign imem_resp = (resp_fifo_rd) + ? (resp_fifo_dout.hresp == 1'b1) + ? SCR1_MEM_RESP_RDY_OK + : SCR1_MEM_RESP_RDY_ER + : SCR1_MEM_RESP_NOTRDY ; `ifdef SCR1_TRGT_SIMULATION
diff --git a/verilog/rtl/syntacore/scr1/src/top/scr1_top_wb.sv b/verilog/rtl/syntacore/scr1/src/top/scr1_top_wb.sv index 97f565c..d72afd1 100644 --- a/verilog/rtl/syntacore/scr1/src/top/scr1_top_wb.sv +++ b/verilog/rtl/syntacore/scr1/src/top/scr1_top_wb.sv
@@ -17,6 +17,9 @@ //// Revision : //// //// v0: June 7, 2021, Dinesh A //// //// wishbone integration //// +//// v1: June 17, 2021, Dinesh A //// +//// core and wishbone clock domain are seperated //// +//// Async fifo added in imem and dmem path //// //// //// ////////////////////////////////////////////////////////////////////// //// //// @@ -69,7 +72,7 @@ input logic cpu_rst_n, // CPU Reset (Core Reset) input logic test_mode, // Test mode input logic test_rst_n, // Test mode's reset - input logic clk, // System clock + input logic core_clk, // Core clock input logic rtc_clk, // Real-time clock `ifdef SCR1_DBG_EN output logic sys_rst_n_o, // External System Reset output @@ -103,6 +106,8 @@ output logic tdo_en, `endif // SCR1_DBG_EN + input logic wb_rst_n, // Wish bone reset + input logic wb_clk, // wish bone clock // Instruction Memory Interface output logic wbd_imem_stb_o, // strobe/request output logic [SCR1_WB_WIDTH-1:0] wbd_imem_adr_o, // address @@ -219,7 +224,7 @@ .STAGES_AMOUNT (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM) ) i_pwrup_rstn_reset_sync ( .rst_n (pwrup_rst_n ), - .clk (clk ), + .clk (core_clk ), .test_rst_n (test_rst_n ), .test_mode (test_mode ), .rst_n_in (1'b1 ), @@ -231,7 +236,7 @@ .STAGES_AMOUNT (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM) ) i_rstn_reset_sync ( .rst_n (pwrup_rst_n ), - .clk (clk ), + .clk (core_clk ), .test_rst_n (test_rst_n ), .test_mode (test_mode ), .rst_n_in (rst_n ), @@ -243,7 +248,7 @@ .STAGES_AMOUNT (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM) ) i_cpu_rstn_reset_sync ( .rst_n (pwrup_rst_n ), - .clk (clk ), + .clk (core_clk ), .test_rst_n (test_rst_n ), .test_mode (test_mode ), .rst_n_in (cpu_rst_n ), @@ -270,7 +275,7 @@ .cpu_rst_n (cpu_rst_n_sync ), .test_mode (test_mode ), .test_rst_n (test_rst_n ), - .clk (clk ), + .clk (core_clk ), .core_rst_n_o (core_rst_n_local ), .core_rdc_qlfy_o ( ), `ifdef SCR1_DBG_EN @@ -333,7 +338,7 @@ scr1_tcm #( .SCR1_TCM_SIZE (`SCR1_DMEM_AWIDTH'(~SCR1_TCM_ADDR_MASK + 1'b1)) ) i_tcm ( - .clk (clk ), + .clk (core_clk ), .rst_n (core_rst_n_local), // Instruction interface to TCM @@ -362,7 +367,7 @@ scr1_timer i_timer ( // Common .rst_n (core_rst_n_local ), - .clk (clk ), + .clk (core_clk ), .rtc_clk (rtc_clk ), // Memory interface @@ -392,7 +397,7 @@ `endif // SCR1_TCM_EN ) i_imem_router ( .rst_n (core_rst_n_local ), - .clk (clk ), + .clk (core_clk ), // Interface to core .imem_req_ack (core_imem_req_ack), .imem_req (core_imem_req ), @@ -447,7 +452,7 @@ ) i_dmem_router ( .rst_n (core_rst_n_local ), - .clk (clk ), + .clk (core_clk ), // Interface to core .dmem_req_ack (core_dmem_req_ack ), .dmem_req (core_dmem_req ), @@ -502,8 +507,8 @@ // Instruction memory WB bridge //------------------------------------------------------------------------------- scr1_imem_wb i_imem_wb ( - .rst_n (core_rst_n_local ), - .clk (clk ), + .core_rst_n (core_rst_n_local ), + .core_clk (core_clk ), // Interface to imem router .imem_req_ack (wb_imem_req_ack ), .imem_req (wb_imem_req ), @@ -511,6 +516,8 @@ .imem_rdata (wb_imem_rdata ), .imem_resp (wb_imem_resp ), // WB interface + .wb_rst_n (wb_rst_n ), + .wb_clk (wb_clk ), .wbd_stb_o (wbd_imem_stb_o ), .wbd_adr_o (wbd_imem_adr_o ), .wbd_we_o (wbd_imem_we_o ), @@ -526,8 +533,8 @@ // Data memory WB bridge //------------------------------------------------------------------------------- scr1_dmem_wb i_dmem_wb ( - .rst_n (core_rst_n_local ), - .clk (clk ), + .core_rst_n (core_rst_n_local ), + .core_clk (core_clk ), // Interface to dmem router .dmem_req_ack (wb_dmem_req_ack ), .dmem_req (wb_dmem_req ), @@ -538,6 +545,8 @@ .dmem_rdata (wb_dmem_rdata ), .dmem_resp (wb_dmem_resp ), // WB interface + .wb_rst_n (wb_rst_n ), + .wb_clk (wb_clk ), .wbd_stb_o (wbd_dmem_stb_o ), .wbd_adr_o (wbd_dmem_adr_o ), .wbd_we_o (wbd_dmem_we_o ),
diff --git a/verilog/rtl/uprj_netlists.v b/verilog/rtl/uprj_netlists.v index b97154e..689eca3 100644 --- a/verilog/rtl/uprj_netlists.v +++ b/verilog/rtl/uprj_netlists.v
@@ -46,6 +46,7 @@ `include "digital_core/src/glbl_cfg.sv" `include "digital_core/src/digital_core.sv" + `include "lib/wb_stagging.sv" `include "wb_interconnect/src/wb_arb.sv" `include "wb_interconnect/src/wb_interconnect.sv"
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v index 976047b..8e7547b 100644 --- a/verilog/rtl/user_project_wrapper.v +++ b/verilog/rtl/user_project_wrapper.v
@@ -97,7 +97,7 @@ .wb_clk_i(wb_clk_i), .wb_rst_i(wb_rst_i), - .rtc_clk(user_clock2), + .user_clock2(user_clock2), // MGMT SoC Wishbone Slave
diff --git a/verilog/rtl/wb_interconnect/src/wb_interconnect.sv b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv index b3552ec..b2e1df2 100644 --- a/verilog/rtl/wb_interconnect/src/wb_interconnect.sv +++ b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
@@ -17,6 +17,9 @@ //// //// //// Revision : //// //// 0.1 - 12th June 2021, Dinesh A //// +//// 0.2 - 17th June 2021, Dinesh A //// +//// Stagging FF added at Slave Interface to break //// +//// path //// //// //// ////////////////////////////////////////////////////////////////////// //// //// @@ -238,43 +241,43 @@ assign m2_wbd_ack_o = m2_wb_rd.wbd_ack; assign m2_wbd_err_o = m2_wb_rd.wbd_err; -assign s0_wb_rd.wbd_dat = s0_wbd_dat_i ; -assign s0_wb_rd.wbd_ack = s0_wbd_ack_i ; -assign s0_wb_rd.wbd_err = s0_wbd_err_i ; - -assign s1_wb_rd.wbd_dat = s1_wbd_dat_i ; -assign s1_wb_rd.wbd_ack = s1_wbd_ack_i ; -assign s1_wb_rd.wbd_err = s1_wbd_err_i ; - -assign s2_wb_rd.wbd_dat = s2_wbd_dat_i ; -assign s2_wb_rd.wbd_ack = s2_wbd_ack_i ; -assign s2_wb_rd.wbd_err = s2_wbd_err_i ; - - //---------------------------------------- // Slave Mapping // ------------------------------------- +// Masked Now and added stagging FF now +// assign s0_wbd_dat_o = s0_wb_wr.wbd_dat ; +// assign s0_wbd_adr_o = s0_wb_wr.wbd_adr ; +// assign s0_wbd_sel_o = s0_wb_wr.wbd_sel ; +// assign s0_wbd_we_o = s0_wb_wr.wbd_we ; +// assign s0_wbd_cyc_o = s0_wb_wr.wbd_cyc ; +// assign s0_wbd_stb_o = s0_wb_wr.wbd_stb ; +// +// assign s1_wbd_dat_o = s1_wb_wr.wbd_dat ; +// assign s1_wbd_adr_o = s1_wb_wr.wbd_adr ; +// assign s1_wbd_sel_o = s1_wb_wr.wbd_sel ; +// assign s1_wbd_we_o = s1_wb_wr.wbd_we ; +// assign s1_wbd_cyc_o = s1_wb_wr.wbd_cyc ; +// assign s1_wbd_stb_o = s1_wb_wr.wbd_stb ; +// +// assign s2_wbd_dat_o = s2_wb_wr.wbd_dat ; +// assign s2_wbd_adr_o = s2_wb_wr.wbd_adr ; +// assign s2_wbd_sel_o = s2_wb_wr.wbd_sel ; +// assign s2_wbd_we_o = s2_wb_wr.wbd_we ; +// assign s2_wbd_cyc_o = s2_wb_wr.wbd_cyc ; +// assign s2_wbd_stb_o = s2_wb_wr.wbd_stb ; +// +// assign s0_wb_rd.wbd_dat = s0_wbd_dat_i ; +// assign s0_wb_rd.wbd_ack = s0_wbd_ack_i ; +// assign s0_wb_rd.wbd_err = s0_wbd_err_i ; +// +// assign s1_wb_rd.wbd_dat = s1_wbd_dat_i ; +// assign s1_wb_rd.wbd_ack = s1_wbd_ack_i ; +// assign s1_wb_rd.wbd_err = s1_wbd_err_i ; +// +// assign s2_wb_rd.wbd_dat = s2_wbd_dat_i ; +// assign s2_wb_rd.wbd_ack = s2_wbd_ack_i ; +// assign s2_wb_rd.wbd_err = s2_wbd_err_i ; -assign s0_wbd_dat_o = s0_wb_wr.wbd_dat ; -assign s0_wbd_adr_o = s0_wb_wr.wbd_adr ; -assign s0_wbd_sel_o = s0_wb_wr.wbd_sel ; -assign s0_wbd_we_o = s0_wb_wr.wbd_we ; -assign s0_wbd_cyc_o = s0_wb_wr.wbd_cyc ; -assign s0_wbd_stb_o = s0_wb_wr.wbd_stb ; - -assign s1_wbd_dat_o = s1_wb_wr.wbd_dat ; -assign s1_wbd_adr_o = s1_wb_wr.wbd_adr ; -assign s1_wbd_sel_o = s1_wb_wr.wbd_sel ; -assign s1_wbd_we_o = s1_wb_wr.wbd_we ; -assign s1_wbd_cyc_o = s1_wb_wr.wbd_cyc ; -assign s1_wbd_stb_o = s1_wb_wr.wbd_stb ; - -assign s2_wbd_dat_o = s2_wb_wr.wbd_dat ; -assign s2_wbd_adr_o = s2_wb_wr.wbd_adr ; -assign s2_wbd_sel_o = s2_wb_wr.wbd_sel ; -assign s2_wbd_we_o = s2_wb_wr.wbd_we ; -assign s2_wbd_cyc_o = s2_wb_wr.wbd_cyc ; -assign s2_wbd_stb_o = s2_wb_wr.wbd_stb ; // // arbitor @@ -284,9 +287,9 @@ wb_arb u_wb_arb( .clk(clk_i), .rstn(rst_n), - .req({ m2_wbd_cyc_i, - m1_wbd_cyc_i, - m0_wbd_cyc_i}), + .req({ m2_wbd_stb_i & !m2_wbd_ack_o, + m1_wbd_stb_i & !m1_wbd_ack_o, + m0_wbd_stb_i & !m0_wbd_ack_o}), .gnt(gnt) ); @@ -326,5 +329,89 @@ +// Wishbone Stagging FF towards S0 to break timing path +wb_stagging u_s0_wb_stage( + .clk_i (clk_i ), + .rst_n (rst_n ), + // WishBone Input master I/P + .m_wbd_dat_i (s0_wb_wr.wbd_dat ), + .m_wbd_adr_i (s0_wb_wr.wbd_adr ), + .m_wbd_sel_i (s0_wb_wr.wbd_sel ), + .m_wbd_we_i (s0_wb_wr.wbd_we ), + .m_wbd_cyc_i (s0_wb_wr.wbd_cyc ), + .m_wbd_stb_i (s0_wb_wr.wbd_stb ), + .m_wbd_dat_o (s0_wb_rd.wbd_dat ), + .m_wbd_ack_o (s0_wb_rd.wbd_ack ), + .m_wbd_err_o (s0_wb_rd.wbd_err ), + + // Slave Interface + .s_wbd_dat_i (s0_wbd_dat_i ), + .s_wbd_ack_i (s0_wbd_ack_i ), + .s_wbd_err_i (s0_wbd_err_i ), + .s_wbd_dat_o (s0_wbd_dat_o ), + .s_wbd_adr_o (s0_wbd_adr_o ), + .s_wbd_sel_o (s0_wbd_sel_o ), + .s_wbd_we_o (s0_wbd_we_o ), + .s_wbd_cyc_o (s0_wbd_cyc_o ), + .s_wbd_stb_o (s0_wbd_stb_o ) + +); + +// Wishbone Stagging FF towards S1 to break timing path +wb_stagging u_s1_wb_stage( + .clk_i (clk_i ), + .rst_n (rst_n ), + // WishBone Input master I/P + .m_wbd_dat_i (s1_wb_wr.wbd_dat ), + .m_wbd_adr_i (s1_wb_wr.wbd_adr ), + .m_wbd_sel_i (s1_wb_wr.wbd_sel ), + .m_wbd_we_i (s1_wb_wr.wbd_we ), + .m_wbd_cyc_i (s1_wb_wr.wbd_cyc ), + .m_wbd_stb_i (s1_wb_wr.wbd_stb ), + .m_wbd_dat_o (s1_wb_rd.wbd_dat ), + .m_wbd_ack_o (s1_wb_rd.wbd_ack ), + .m_wbd_err_o (s1_wb_rd.wbd_err ), + + // Slave Interface + .s_wbd_dat_i (s1_wbd_dat_i ), + .s_wbd_ack_i (s1_wbd_ack_i ), + .s_wbd_err_i (s1_wbd_err_i ), + .s_wbd_dat_o (s1_wbd_dat_o ), + .s_wbd_adr_o (s1_wbd_adr_o ), + .s_wbd_sel_o (s1_wbd_sel_o ), + .s_wbd_we_o (s1_wbd_we_o ), + .s_wbd_cyc_o (s1_wbd_cyc_o ), + .s_wbd_stb_o (s1_wbd_stb_o ) + +); + +// Wishbone Stagging FF towards S1 to break timing path +wb_stagging u_s2_wb_stage( + .clk_i (clk_i ), + .rst_n (rst_n ), + // WishBone Input master I/P + .m_wbd_dat_i (s2_wb_wr.wbd_dat ), + .m_wbd_adr_i (s2_wb_wr.wbd_adr ), + .m_wbd_sel_i (s2_wb_wr.wbd_sel ), + .m_wbd_we_i (s2_wb_wr.wbd_we ), + .m_wbd_cyc_i (s2_wb_wr.wbd_cyc ), + .m_wbd_stb_i (s2_wb_wr.wbd_stb ), + .m_wbd_dat_o (s2_wb_rd.wbd_dat ), + .m_wbd_ack_o (s2_wb_rd.wbd_ack ), + .m_wbd_err_o (s2_wb_rd.wbd_err ), + + // Slave Interface + .s_wbd_dat_i (s2_wbd_dat_i ), + .s_wbd_ack_i (s2_wbd_ack_i ), + .s_wbd_err_i (s2_wbd_err_i ), + .s_wbd_dat_o (s2_wbd_dat_o ), + .s_wbd_adr_o (s2_wbd_adr_o ), + .s_wbd_sel_o (s2_wbd_sel_o ), + .s_wbd_we_o (s2_wbd_we_o ), + .s_wbd_cyc_o (s2_wbd_cyc_o ), + .s_wbd_stb_o (s2_wbd_stb_o ) + +); + endmodule