From 51f4d3992a8e02764bfeac7246c9a3c9c5dc15fc Mon Sep 17 00:00:00 2001 From: M0stafaRady Date: Sun, 12 Jan 2025 17:12:31 +0200 Subject: [PATCH] update wrappers and docs with the latest buswrap updates --- EF_SPI.yaml | 4 +- README.md | 77 +-- hdl/rtl/bus_wrappers/EF_SPI_AHBL.dev.v | 263 ++++++++ hdl/rtl/bus_wrappers/EF_SPI_AHBL.pp.v | 388 ----------- hdl/rtl/bus_wrappers/EF_SPI_AHBL.v | 601 +++++++++++------- hdl/rtl/bus_wrappers/EF_SPI_APB.dev.v | 263 ++++++++ hdl/rtl/bus_wrappers/EF_SPI_APB.pp.v | 372 ----------- hdl/rtl/bus_wrappers/EF_SPI_APB.v | 583 ++++++++++------- hdl/rtl/bus_wrappers/EF_SPI_WB.dev.v | 268 ++++++++ hdl/rtl/bus_wrappers/EF_SPI_WB.pp.v | 335 ---------- hdl/rtl/bus_wrappers/EF_SPI_WB.v | 569 ++++++++++------- .../bus_wrappers/dft/EF_SPI_AHBL_DFT.dev.v | 264 ++++++++ hdl/rtl/bus_wrappers/dft/EF_SPI_AHBL_DFT.v | 399 ++++++++++++ hdl/rtl/bus_wrappers/dft/EF_SPI_APB_DFT.dev.v | 264 ++++++++ hdl/rtl/bus_wrappers/dft/EF_SPI_APB_DFT.v | 381 +++++++++++ hdl/rtl/bus_wrappers/dft/EF_SPI_WB_DFT.dev.v | 269 ++++++++ hdl/rtl/bus_wrappers/dft/EF_SPI_WB_DFT.v | 361 +++++++++++ ip/dependencies.json | 2 +- ipm_package.bash | 55 ++ verify/README.md | 31 + verify/uvm-python/Makefile | 8 +- 21 files changed, 3905 insertions(+), 1852 deletions(-) create mode 100644 hdl/rtl/bus_wrappers/EF_SPI_AHBL.dev.v delete mode 100644 hdl/rtl/bus_wrappers/EF_SPI_AHBL.pp.v create mode 100644 hdl/rtl/bus_wrappers/EF_SPI_APB.dev.v delete mode 100644 hdl/rtl/bus_wrappers/EF_SPI_APB.pp.v create mode 100644 hdl/rtl/bus_wrappers/EF_SPI_WB.dev.v delete mode 100644 hdl/rtl/bus_wrappers/EF_SPI_WB.pp.v create mode 100644 hdl/rtl/bus_wrappers/dft/EF_SPI_AHBL_DFT.dev.v create mode 100644 hdl/rtl/bus_wrappers/dft/EF_SPI_AHBL_DFT.v create mode 100644 hdl/rtl/bus_wrappers/dft/EF_SPI_APB_DFT.dev.v create mode 100644 hdl/rtl/bus_wrappers/dft/EF_SPI_APB_DFT.v create mode 100644 hdl/rtl/bus_wrappers/dft/EF_SPI_WB_DFT.dev.v create mode 100644 hdl/rtl/bus_wrappers/dft/EF_SPI_WB_DFT.v create mode 100644 ipm_package.bash create mode 100644 verify/README.md diff --git a/EF_SPI.yaml b/EF_SPI.yaml index 417f77c..65cfc2e 100644 --- a/EF_SPI.yaml +++ b/EF_SPI.yaml @@ -5,8 +5,8 @@ info: repo: github.com/efabless/EF_SPI owner: Efabless Corp. license: APACHE 2.0 - author: Mohamed Shalan - email: mshalan@efabless.com + author: Efabless Corp. + email: ip_admin@efabless.com version: v1.0.11 date: 17-09-2024 category: digital diff --git a/README.md b/README.md index 31958cd..b371b48 100644 --- a/README.md +++ b/README.md @@ -4,21 +4,30 @@ SPI master controller with receive and transmit FIFOs. ## The wrapped IP - APB, AHBL, and Wishbone wrappers, generated by the [BusWrap](https://github.com/efabless/BusWrap/tree/main) `bus_wrap.py` utility, are provided. All wrappers provide the same programmer's interface as outlined in the following sections. + APB, AHBL, and Wishbone wrappers are provided. All wrappers provide the same programmer's interface as outlined in the following sections. #### Wrapped IP System Integration -Based on your use case, use one of the provided wrappers or create a wrapper for your system bus type. For an example of how to integrate the APB wrapper: +Based on your use case, use one of the provided wrappers or create a wrapper for your system bus type. For an example of how to integrate the wishbone wrapper: ```verilog -EF_SPI_APB INST ( - `TB_APB_SLAVE_CONN, +EF_SPI_WB INST ( + .clk_i(clk_i), + .rst_i(rst_i), + .adr_i(adr_i), + .dat_i(dat_i), + .dat_o(dat_o), + .sel_i(sel_i), + .cyc_i(cyc_i), + .stb_i(stb_i), + .ack_o(ack_o), + .we_i(we_i), + .IRQ(irq), .miso(miso), .mosi(mosi), .csb(csb), .sclk(sclk) ); ``` -> **_NOTE:_** `TB_APB_SLAVE_CONN is a convenient macro provided by [BusWrap](https://github.com/efabless/BusWrap/tree/main). #### Wrappers with DFT support Wrappers in the directory ``/hdl/rtl/bus_wrappers/DFT`` have an extra input port ``sc_testmode`` to enable the clock gate whenever the scan chain testmode is enabled. @@ -95,7 +104,7 @@ SPI clock Prescaler; should have a value >= 2. SPI Clock Frequency = System Cloc ### STATUS Register [Offset: 0x14, mode: r] Status resgister - + |bit|field name|width|description| |---|---|---|---| @@ -105,6 +114,8 @@ Status resgister |3|RX_F|1|Receive FIFO is Full.| |4|TX_B|1|Transmit FIFO level is Below Threshold.| |5|RX_A|1|Receive FIFO level is Above Threshold.| +|6|busy|1|spi busy flag.| +|7|done|1|spi done flag.| ### RX_FIFO_LEVEL Register [Offset: 0xfe00, mode: r] @@ -172,7 +183,7 @@ TX_FIFO Flush Register ### Interrupt Flags -The wrapped IP provides four registers to deal with interrupts: IM, RIS, MIS and IC. These registers exist for all wrapper types generated by the [BusWrap](https://github.com/efabless/BusWrap/tree/main) `bus_wrap.py` utility. +The wrapped IP provides four registers to deal with interrupts: IM, RIS, MIS and IC. These registers exist for all wrapper types. Each register has a group of bits for the interrupt sources/flags. - `IM` [offset: 0xff00]: is used to enable/disable interrupt sources. @@ -195,7 +206,12 @@ The following are the bit definitions for the interrupt registers: |4|TXB|1|Transmit FIFO level is Below Threshold.| |5|RXA|1|Receive FIFO level is Above Threshold.| ### Clock Gating -The IP has clock gating feature, enabling the selective activation and deactivation of the clock as required through the ``GCLK`` register. This functionality is implemented through the ``ef_gating_cell``, which is part of the the common modules library, [aucohl_lib.v](https://github.com/efabless/IP_Utilities/blob/main/rtl/aucohl_lib.v). By default, the cell operates with a behavioral implementation, but when the ``SKY130`` macro is enabled, the ``sky130_fd_sc_hd__dlclkp_4`` clock gating cell is used. +The IP has clock gating feature, enabling the selective activation and deactivation of the clock as required through the ``GCLK`` register. This functionality is implemented through the ``ef_util_gating_cell``, which is part of the the common modules library, [ef_util_lib.v](https://github.com/efabless/EF_IP_UTIL/blob/main/hdl/ef_util_lib.v). By default, the cell operates with a behavioral implementation, but when the ``CLKG_SKY130_HD`` macro is enabled, the ``sky130_fd_sc_hd__dlclkp_4`` clock gating cell is used. +**Note:** If you choose the [OpenLane2](https://github.com/efabless/openlane2) flow for implementation and would like to add the clock gating feature, you need to add ``SKY130`` macro to the ``VERILOG_DEFINES`` configuration variable. Update the YAML configuration file as follows: +``` +VERILOG_DEFINES: +- SKY130 +``` ### The Interface @@ -238,47 +254,16 @@ The IP has clock gating feature, enabling the selective activation and deactivat |tx_level|output|FAW|TX FIFO data level.| |ss|input|1|None| |enable|input|1|enable for spi master pulse generation| -## F/W Usage Guidelines: -1. Set the prescaler by writing to the ``PR`` register where SPI Clock Frequency = System Clock / PR. Note: should have a value >= 2. -2. Configure clock polarity and clock phase bu setting ``cpol`` and ``cpha`` fields in the ``CFG`` register. -3. Set the ``SSn`` field in the ``CTRL`` register - +|done|output|1|spi done flag.| +|busy|output|1|spi busy flag.| +## Firmware Drivers: +Firmware drivers for EF_SPI can be found in the [fw](https://github.com/efabless/EF_SPI/tree/main/fw) directory. EF_SPI driver documentation is available [here](https://github.com/efabless/EF_SPI/blob/main/fw/README.md). +You can also find an example C application using the EF_SPI drivers [here](). ## Installation: You can either clone repo or use [IPM](https://github.com/efabless/IPM) which is an open-source IPs Package Manager * To clone repo: ```git clone https://github.com/efabless/EF_SPI``` -> **Note:** If you choose this method, you need to clone [IP_Utilities](https://github.com/efabless/IP_Utilities/tree/main) repository, as it includes required modules from the common modules library, [aucohl_lib.v](https://github.com/efabless/IP_Utilities/blob/main/rtl/aucohl_lib.v) +> **Note:** If you choose this method, you need to clone [EF_IP_UTIL](https://github.com/efabless/EF_IP_UTIL.git) repository, as it includes required modules from the common modules library, [ef_util_lib.v](https://github.com/efabless/EF_IP_UTIL/blob/main/hdl/ef_util_lib.v) * To download via IPM , follow installation guides [here](https://github.com/efabless/IPM/blob/main/README.md) then run ```ipm install EF_SPI``` -> **Note:** This method is recommended as it automatically installs [IP_Utilities](https://github.com/efabless/IP_Utilities/tree/main) as a dependency. -### Run cocotb UVM Testbench: -In IP directory run: - ```shell - cd verify/uvm-python/ - ``` - ##### To run testbench for design with APB - To run all tests: - ```shell - make run_all_tests BUS_TYPE=APB - ``` - To run a certain test: - ```shell - make run_ BUS_TYPE=APB - ``` - To run all tests with a tag: - ```shell - make run_all_tests TAG= BUS_TYPE=APB - ``` - ##### To run testbench for design with APB - To run all tests: - ```shell - make run_all_tests BUS_TYPE=AHB - ``` - To run a certain test: - ```shell - make run_ BUS_TYPE=AHB - ``` - To run all tests with a tag: - ```shell - make run_all_tests TAG= BUS_TYPE=AHB -``` +> **Note:** This method is recommended as it automatically installs [EF_IP_UTIL](https://github.com/efabless/EF_IP_UTIL.git) as a dependency. diff --git a/hdl/rtl/bus_wrappers/EF_SPI_AHBL.dev.v b/hdl/rtl/bus_wrappers/EF_SPI_AHBL.dev.v new file mode 100644 index 0000000..c1c4ed7 --- /dev/null +++ b/hdl/rtl/bus_wrappers/EF_SPI_AHBL.dev.v @@ -0,0 +1,263 @@ +/* + Copyright 2024 Efabless Corp. + + Author: Efabless Corp. (ip_admin@efabless.com) + + 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. + +*/ + +/* THIS FILE IS GENERATED, DO NOT EDIT */ + +`timescale 1ns/1ps +`default_nettype none + +`define AHBL_AW 16 + +`include "ahbl_wrapper.vh" + +module EF_SPI_AHBL #( + parameter + CDW = 8, + FAW = 4 +) ( +`ifdef USE_POWER_PINS + inout VPWR, + inout VGND, +`endif + `AHBL_SLAVE_PORTS, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk +); + + localparam RXDATA_REG_OFFSET = `AHBL_AW'h0000; + localparam TXDATA_REG_OFFSET = `AHBL_AW'h0004; + localparam CFG_REG_OFFSET = `AHBL_AW'h0008; + localparam CTRL_REG_OFFSET = `AHBL_AW'h000C; + localparam PR_REG_OFFSET = `AHBL_AW'h0010; + localparam STATUS_REG_OFFSET = `AHBL_AW'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = `AHBL_AW'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = `AHBL_AW'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = `AHBL_AW'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = `AHBL_AW'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = `AHBL_AW'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = `AHBL_AW'hFE18; + localparam IM_REG_OFFSET = `AHBL_AW'hFF00; + localparam MIS_REG_OFFSET = `AHBL_AW'hFF04; + localparam RIS_REG_OFFSET = `AHBL_AW'hFF08; + localparam IC_REG_OFFSET = `AHBL_AW'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell( + `ifdef USE_POWER_PINS + .vpwr(VPWR), + .vgnd(VGND), + `endif // USE_POWER_PINS + .clk(HCLK), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = HRESETn; + + + `AHBL_CTRL_SIGNALS + + wire [1-1:0] CPOL; + wire [1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [1-1:0] wr; + wire [1-1:0] rd; + wire [8-1:0] datai; + wire [8-1:0] datao; + wire [1-1:0] rx_en; + wire [1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [1-1:0] rx_empty; + wire [1-1:0] rx_full; + wire [1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [1-1:0] tx_empty; + wire [1-1:0] tx_full; + wire [1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [1-1:0] ss; + wire [1-1:0] enable; + wire [1-1:0] done; + wire [1-1:0] busy; + + // Register Definitions + wire [8-1:0] RXDATA_WIRE; + + wire [8-1:0] TXDATA_WIRE; + + reg [1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + `AHBL_REG(CFG_REG, 0, 2) + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + `AHBL_REG(CTRL_REG, 0, 3) + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + `AHBL_REG(PR_REG, 'h2, CDW) + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `AHBL_REG(RX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + `AHBL_REG_AC(RX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `AHBL_REG(TX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + `AHBL_REG_AC(TX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + localparam GCLK_REG_OFFSET = `AHBL_AW'hFF10; + `AHBL_REG(GCLK_REG, 0, 1) + + reg [5:0] IM_REG; + reg [5:0] IC_REG; + reg [5:0] RIS_REG; + + `AHBL_MIS_REG(6) + `AHBL_REG(IM_REG, 0, 6) + `AHBL_IC_REG(6) + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + `AHBL_BLOCK(RIS_REG, 0) else begin + for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign HRDATA = + (last_HADDR[`AHBL_AW-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (last_HADDR[`AHBL_AW-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (last_HADDR[`AHBL_AW-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (last_HADDR[`AHBL_AW-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (last_HADDR[`AHBL_AW-1:0] == PR_REG_OFFSET) ? PR_REG : + (last_HADDR[`AHBL_AW-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (last_HADDR[`AHBL_AW-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (last_HADDR[`AHBL_AW-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (last_HADDR[`AHBL_AW-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (last_HADDR[`AHBL_AW-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (last_HADDR[`AHBL_AW-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (last_HADDR[`AHBL_AW-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (last_HADDR[`AHBL_AW-1:0] == IM_REG_OFFSET) ? IM_REG : + (last_HADDR[`AHBL_AW-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (last_HADDR[`AHBL_AW-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (last_HADDR[`AHBL_AW-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : + 32'hDEADBEEF; + + assign HREADYOUT = 1'b1; + + assign RXDATA_WIRE = datao; + assign rd = (ahbl_re & (last_HADDR[`AHBL_AW-1:0] == RXDATA_REG_OFFSET)); + assign datai = HWDATA; + assign wr = (ahbl_we & (last_HADDR[`AHBL_AW-1:0] == TXDATA_REG_OFFSET)); +endmodule diff --git a/hdl/rtl/bus_wrappers/EF_SPI_AHBL.pp.v b/hdl/rtl/bus_wrappers/EF_SPI_AHBL.pp.v deleted file mode 100644 index e964c38..0000000 --- a/hdl/rtl/bus_wrappers/EF_SPI_AHBL.pp.v +++ /dev/null @@ -1,388 +0,0 @@ -/* - Copyright 2024 Efabless Corp. - - Author: Mohamed Shalan (mshalan@efabless.com) - - 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. - -*/ - -/* THIS FILE IS GENERATED, DO NOT EDIT */ - -`timescale 1ns/1ps -`default_nettype none - - - -/* - Copyright 2020 AUCOHL - - Author: Mohamed Shalan (mshalan@aucegypt.edu) - - 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. -*/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -module EF_SPI_AHBL #( - parameter - CDW = 8, - FAW = 4 -) ( - - - - - input wire HCLK, - input wire HRESETn, - input wire HWRITE, - input wire [31:0] HWDATA, - input wire [31:0] HADDR, - input wire [1:0] HTRANS, - input wire HSEL, - input wire HREADY, - output wire HREADYOUT, - output wire [31:0] HRDATA, - output wire IRQ -, - input wire [1-1:0] miso, - output wire [1-1:0] mosi, - output wire [1-1:0] csb, - output wire [1-1:0] sclk -); - - localparam RXDATA_REG_OFFSET = 16'h0000; - localparam TXDATA_REG_OFFSET = 16'h0004; - localparam CFG_REG_OFFSET = 16'h0008; - localparam CTRL_REG_OFFSET = 16'h000C; - localparam PR_REG_OFFSET = 16'h0010; - localparam STATUS_REG_OFFSET = 16'h0014; - localparam RX_FIFO_LEVEL_REG_OFFSET = 16'hFE00; - localparam RX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE04; - localparam RX_FIFO_FLUSH_REG_OFFSET = 16'hFE08; - localparam TX_FIFO_LEVEL_REG_OFFSET = 16'hFE10; - localparam TX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE14; - localparam TX_FIFO_FLUSH_REG_OFFSET = 16'hFE18; - localparam IM_REG_OFFSET = 16'hFF00; - localparam MIS_REG_OFFSET = 16'hFF04; - localparam RIS_REG_OFFSET = 16'hFF08; - localparam IC_REG_OFFSET = 16'hFF0C; - - reg [0:0] GCLK_REG; - wire clk_g; - wire clk_gated_en = GCLK_REG[0]; - ef_gating_cell clk_gate_cell( - - - - // USE_POWER_PINS - .clk(HCLK), - .clk_en(clk_gated_en), - .clk_o(clk_g) - ); - - wire clk = clk_g; - wire rst_n = HRESETn; - - - reg last_HSEL, last_HWRITE; reg [31:0] last_HADDR; reg [1:0] last_HTRANS; - always@ (posedge HCLK or negedge HRESETn) begin - if(~HRESETn) begin - last_HSEL <= 1'b0; - last_HADDR <= 1'b0; - last_HWRITE <= 1'b0; - last_HTRANS <= 1'b0; - end else if(HREADY) begin - last_HSEL <= HSEL; - last_HADDR <= HADDR; - last_HWRITE <= HWRITE; - last_HTRANS <= HTRANS; - end - end - wire ahbl_valid = last_HSEL & last_HTRANS[1]; - wire ahbl_we = last_HWRITE & ahbl_valid; - wire ahbl_re = ~last_HWRITE & ahbl_valid; - - wire [1-1:0] CPOL; - wire [1-1:0] CPHA; - wire [CDW-1:0] clk_divider; - wire [1-1:0] wr; - wire [1-1:0] rd; - wire [8-1:0] datai; - wire [8-1:0] datao; - wire [1-1:0] rx_en; - wire [1-1:0] rx_flush; - wire [FAW-1:0] rx_threshold; - wire [1-1:0] rx_empty; - wire [1-1:0] rx_full; - wire [1-1:0] rx_level_above; - wire [FAW-1:0] rx_level; - wire [1-1:0] tx_flush; - wire [FAW-1:0] tx_threshold; - wire [1-1:0] tx_empty; - wire [1-1:0] tx_full; - wire [1-1:0] tx_level_below; - wire [FAW-1:0] tx_level; - wire [1-1:0] ss; - wire [1-1:0] enable; - wire [1-1:0] done; - wire [1-1:0] busy; - - // Register Definitions - wire [8-1:0] RXDATA_WIRE; - - wire [8-1:0] TXDATA_WIRE; - - reg [1:0] CFG_REG; - assign CPOL = CFG_REG[0 : 0]; - assign CPHA = CFG_REG[1 : 1]; - always @(posedge HCLK or negedge HRESETn) if(~HRESETn) CFG_REG <= 0; - else if(ahbl_we & (last_HADDR[16-1:0]==CFG_REG_OFFSET)) - CFG_REG <= HWDATA[2-1:0]; - - reg [2:0] CTRL_REG; - assign ss = CTRL_REG[0 : 0]; - assign enable = CTRL_REG[1 : 1]; - assign rx_en = CTRL_REG[2 : 2]; - always @(posedge HCLK or negedge HRESETn) if(~HRESETn) CTRL_REG <= 0; - else if(ahbl_we & (last_HADDR[16-1:0]==CTRL_REG_OFFSET)) - CTRL_REG <= HWDATA[3-1:0]; - - reg [CDW-1:0] PR_REG; - assign clk_divider = PR_REG; - always @(posedge HCLK or negedge HRESETn) if(~HRESETn) PR_REG <= 'h2; - else if(ahbl_we & (last_HADDR[16-1:0]==PR_REG_OFFSET)) - PR_REG <= HWDATA[CDW-1:0]; - - wire [8-1:0] STATUS_WIRE; - assign STATUS_WIRE[0 : 0] = tx_empty; - assign STATUS_WIRE[1 : 1] = tx_full; - assign STATUS_WIRE[2 : 2] = rx_empty; - assign STATUS_WIRE[3 : 3] = rx_full; - assign STATUS_WIRE[4 : 4] = tx_level_below; - assign STATUS_WIRE[5 : 5] = rx_level_above; - assign STATUS_WIRE[6 : 6] = busy; - assign STATUS_WIRE[7 : 7] = done; - - wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; - assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; - - reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; - assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - always @(posedge HCLK or negedge HRESETn) if(~HRESETn) RX_FIFO_THRESHOLD_REG <= 0; - else if(ahbl_we & (last_HADDR[16-1:0]==RX_FIFO_THRESHOLD_REG_OFFSET)) - RX_FIFO_THRESHOLD_REG <= HWDATA[FAW-1:0]; - - reg [0:0] RX_FIFO_FLUSH_REG; - assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; - always @(posedge HCLK or negedge HRESETn) if(~HRESETn) RX_FIFO_FLUSH_REG <= 0; - else if(ahbl_we & (last_HADDR[16-1:0]==RX_FIFO_FLUSH_REG_OFFSET)) - RX_FIFO_FLUSH_REG <= HWDATA[1-1:0]; - else - RX_FIFO_FLUSH_REG <= 1'h0 & RX_FIFO_FLUSH_REG; - - wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; - assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; - - reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; - assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - always @(posedge HCLK or negedge HRESETn) if(~HRESETn) TX_FIFO_THRESHOLD_REG <= 0; - else if(ahbl_we & (last_HADDR[16-1:0]==TX_FIFO_THRESHOLD_REG_OFFSET)) - TX_FIFO_THRESHOLD_REG <= HWDATA[FAW-1:0]; - - reg [0:0] TX_FIFO_FLUSH_REG; - assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; - always @(posedge HCLK or negedge HRESETn) if(~HRESETn) TX_FIFO_FLUSH_REG <= 0; - else if(ahbl_we & (last_HADDR[16-1:0]==TX_FIFO_FLUSH_REG_OFFSET)) - TX_FIFO_FLUSH_REG <= HWDATA[1-1:0]; - else - TX_FIFO_FLUSH_REG <= 1'h0 & TX_FIFO_FLUSH_REG; - - localparam GCLK_REG_OFFSET = 16'hFF10; - always @(posedge HCLK or negedge HRESETn) if(~HRESETn) GCLK_REG <= 0; - else if(ahbl_we & (last_HADDR[16-1:0]==GCLK_REG_OFFSET)) - GCLK_REG <= HWDATA[1-1:0]; - - reg [5:0] IM_REG; - reg [5:0] IC_REG; - reg [5:0] RIS_REG; - - wire[6-1:0] MIS_REG = RIS_REG & IM_REG; - always @(posedge HCLK or negedge HRESETn) if(~HRESETn) IM_REG <= 0; - else if(ahbl_we & (last_HADDR[16-1:0]==IM_REG_OFFSET)) - IM_REG <= HWDATA[6-1:0]; - always @(posedge HCLK or negedge HRESETn) if(~HRESETn) IC_REG <= 6'b0; - else if(ahbl_we & (last_HADDR[16-1:0]==IC_REG_OFFSET)) - IC_REG <= HWDATA[6-1:0]; - else IC_REG <= 6'd0; - - wire [0:0] TXE = tx_empty; - wire [0:0] TXF = tx_full; - wire [0:0] RXE = rx_empty; - wire [0:0] RXF = rx_full; - wire [0:0] TXB = tx_level_below; - wire [0:0] RXA = rx_level_above; - - - integer _i_; - always @(posedge HCLK or negedge HRESETn) if(~HRESETn) RIS_REG <= 0; else begin - for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - end - - assign IRQ = |MIS_REG; - - EF_SPI #( - .CDW(CDW), - .FAW(FAW) - ) instance_to_wrap ( - .clk(clk), - .rst_n(rst_n), - .CPOL(CPOL), - .CPHA(CPHA), - .clk_divider(clk_divider), - .wr(wr), - .rd(rd), - .datai(datai), - .datao(datao), - .rx_en(rx_en), - .rx_flush(rx_flush), - .rx_threshold(rx_threshold), - .rx_empty(rx_empty), - .rx_full(rx_full), - .rx_level_above(rx_level_above), - .rx_level(rx_level), - .tx_flush(tx_flush), - .tx_threshold(tx_threshold), - .tx_empty(tx_empty), - .tx_full(tx_full), - .tx_level_below(tx_level_below), - .tx_level(tx_level), - .ss(ss), - .enable(enable), - .done(done), - .busy(busy), - .miso(miso), - .mosi(mosi), - .csb(csb), - .sclk(sclk) - ); - - assign HRDATA = - (last_HADDR[16-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : - (last_HADDR[16-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : - (last_HADDR[16-1:0] == CFG_REG_OFFSET) ? CFG_REG : - (last_HADDR[16-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : - (last_HADDR[16-1:0] == PR_REG_OFFSET) ? PR_REG : - (last_HADDR[16-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : - (last_HADDR[16-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : - (last_HADDR[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : - (last_HADDR[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : - (last_HADDR[16-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : - (last_HADDR[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : - (last_HADDR[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : - (last_HADDR[16-1:0] == IM_REG_OFFSET) ? IM_REG : - (last_HADDR[16-1:0] == MIS_REG_OFFSET) ? MIS_REG : - (last_HADDR[16-1:0] == RIS_REG_OFFSET) ? RIS_REG : - (last_HADDR[16-1:0] == IC_REG_OFFSET) ? IC_REG : - (last_HADDR[16-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : - 32'hDEADBEEF; - - assign HREADYOUT = 1'b1; - - assign RXDATA_WIRE = datao; - assign rd = (ahbl_re & (last_HADDR[16-1:0] == RXDATA_REG_OFFSET)); - assign datai = HWDATA; - assign wr = (ahbl_we & (last_HADDR[16-1:0] == TXDATA_REG_OFFSET)); -endmodule diff --git a/hdl/rtl/bus_wrappers/EF_SPI_AHBL.v b/hdl/rtl/bus_wrappers/EF_SPI_AHBL.v index 11824a2..e7525c5 100644 --- a/hdl/rtl/bus_wrappers/EF_SPI_AHBL.v +++ b/hdl/rtl/bus_wrappers/EF_SPI_AHBL.v @@ -1,7 +1,7 @@ /* Copyright 2024 Efabless Corp. - Author: Mohamed Shalan (mshalan@efabless.com) + Author: Efabless Corp. (ip_admin@efabless.com) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,245 +19,380 @@ /* THIS FILE IS GENERATED, DO NOT EDIT */ -`timescale 1ns/1ps -`default_nettype none +`timescale 1ns / 1ps `default_nettype none -`define AHBL_AW 16 -`include "ahbl_wrapper.vh" -module EF_SPI_AHBL #( - parameter - CDW = 8, - FAW = 4 + + + + + + + + + + + + + + + + + + +// PRINT_LICENSE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +module EF_SPI_AHBL #( + parameter CDW = 8, + FAW = 4 ) ( -`ifdef USE_POWER_PINS - inout VPWR, - inout VGND, -`endif - `AHBL_SLAVE_PORTS, - input wire [1-1:0] miso, - output wire [1-1:0] mosi, - output wire [1-1:0] csb, - output wire [1-1:0] sclk + + + + + input wire HCLK, + input wire HRESETn, + input wire HWRITE, + input wire [ 31:0] HWDATA, + input wire [ 31:0] HADDR, + input wire [ 1:0] HTRANS, + input wire HSEL, + input wire HREADY, + output wire HREADYOUT, + output wire [ 31:0] HRDATA, + output wire IRQ, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk ); - localparam RXDATA_REG_OFFSET = `AHBL_AW'h0000; - localparam TXDATA_REG_OFFSET = `AHBL_AW'h0004; - localparam CFG_REG_OFFSET = `AHBL_AW'h0008; - localparam CTRL_REG_OFFSET = `AHBL_AW'h000C; - localparam PR_REG_OFFSET = `AHBL_AW'h0010; - localparam STATUS_REG_OFFSET = `AHBL_AW'h0014; - localparam RX_FIFO_LEVEL_REG_OFFSET = `AHBL_AW'hFE00; - localparam RX_FIFO_THRESHOLD_REG_OFFSET = `AHBL_AW'hFE04; - localparam RX_FIFO_FLUSH_REG_OFFSET = `AHBL_AW'hFE08; - localparam TX_FIFO_LEVEL_REG_OFFSET = `AHBL_AW'hFE10; - localparam TX_FIFO_THRESHOLD_REG_OFFSET = `AHBL_AW'hFE14; - localparam TX_FIFO_FLUSH_REG_OFFSET = `AHBL_AW'hFE18; - localparam IM_REG_OFFSET = `AHBL_AW'hFF00; - localparam MIS_REG_OFFSET = `AHBL_AW'hFF04; - localparam RIS_REG_OFFSET = `AHBL_AW'hFF08; - localparam IC_REG_OFFSET = `AHBL_AW'hFF0C; - - reg [0:0] GCLK_REG; - wire clk_g; - wire clk_gated_en = GCLK_REG[0]; - ef_gating_cell clk_gate_cell( - `ifdef USE_POWER_PINS - .vpwr(VPWR), - .vgnd(VGND), - `endif // USE_POWER_PINS - .clk(HCLK), - .clk_en(clk_gated_en), - .clk_o(clk_g) - ); - - wire clk = clk_g; - wire rst_n = HRESETn; - - - `AHBL_CTRL_SIGNALS - - wire [1-1:0] CPOL; - wire [1-1:0] CPHA; - wire [CDW-1:0] clk_divider; - wire [1-1:0] wr; - wire [1-1:0] rd; - wire [8-1:0] datai; - wire [8-1:0] datao; - wire [1-1:0] rx_en; - wire [1-1:0] rx_flush; - wire [FAW-1:0] rx_threshold; - wire [1-1:0] rx_empty; - wire [1-1:0] rx_full; - wire [1-1:0] rx_level_above; - wire [FAW-1:0] rx_level; - wire [1-1:0] tx_flush; - wire [FAW-1:0] tx_threshold; - wire [1-1:0] tx_empty; - wire [1-1:0] tx_full; - wire [1-1:0] tx_level_below; - wire [FAW-1:0] tx_level; - wire [1-1:0] ss; - wire [1-1:0] enable; - wire [1-1:0] done; - wire [1-1:0] busy; - - // Register Definitions - wire [8-1:0] RXDATA_WIRE; - - wire [8-1:0] TXDATA_WIRE; - - reg [1:0] CFG_REG; - assign CPOL = CFG_REG[0 : 0]; - assign CPHA = CFG_REG[1 : 1]; - `AHBL_REG(CFG_REG, 0, 2) - - reg [2:0] CTRL_REG; - assign ss = CTRL_REG[0 : 0]; - assign enable = CTRL_REG[1 : 1]; - assign rx_en = CTRL_REG[2 : 2]; - `AHBL_REG(CTRL_REG, 0, 3) - - reg [CDW-1:0] PR_REG; - assign clk_divider = PR_REG; - `AHBL_REG(PR_REG, 'h2, CDW) - - wire [8-1:0] STATUS_WIRE; - assign STATUS_WIRE[0 : 0] = tx_empty; - assign STATUS_WIRE[1 : 1] = tx_full; - assign STATUS_WIRE[2 : 2] = rx_empty; - assign STATUS_WIRE[3 : 3] = rx_full; - assign STATUS_WIRE[4 : 4] = tx_level_below; - assign STATUS_WIRE[5 : 5] = rx_level_above; - assign STATUS_WIRE[6 : 6] = busy; - assign STATUS_WIRE[7 : 7] = done; - - wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; - assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; - - reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; - assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - `AHBL_REG(RX_FIFO_THRESHOLD_REG, 0, FAW) - - reg [0:0] RX_FIFO_FLUSH_REG; - assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; - `AHBL_REG_AC(RX_FIFO_FLUSH_REG, 0, 1, 1'h0) - - wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; - assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; - - reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; - assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - `AHBL_REG(TX_FIFO_THRESHOLD_REG, 0, FAW) - - reg [0:0] TX_FIFO_FLUSH_REG; - assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; - `AHBL_REG_AC(TX_FIFO_FLUSH_REG, 0, 1, 1'h0) - - localparam GCLK_REG_OFFSET = `AHBL_AW'hFF10; - `AHBL_REG(GCLK_REG, 0, 1) - - reg [5:0] IM_REG; - reg [5:0] IC_REG; - reg [5:0] RIS_REG; - - `AHBL_MIS_REG(6) - `AHBL_REG(IM_REG, 0, 6) - `AHBL_IC_REG(6) - - wire [0:0] TXE = tx_empty; - wire [0:0] TXF = tx_full; - wire [0:0] RXE = rx_empty; - wire [0:0] RXF = rx_full; - wire [0:0] TXB = tx_level_below; - wire [0:0] RXA = rx_level_above; - - - integer _i_; - `AHBL_BLOCK(RIS_REG, 0) else begin - for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - end - - assign IRQ = |MIS_REG; - - EF_SPI #( - .CDW(CDW), - .FAW(FAW) - ) instance_to_wrap ( - .clk(clk), - .rst_n(rst_n), - .CPOL(CPOL), - .CPHA(CPHA), - .clk_divider(clk_divider), - .wr(wr), - .rd(rd), - .datai(datai), - .datao(datao), - .rx_en(rx_en), - .rx_flush(rx_flush), - .rx_threshold(rx_threshold), - .rx_empty(rx_empty), - .rx_full(rx_full), - .rx_level_above(rx_level_above), - .rx_level(rx_level), - .tx_flush(tx_flush), - .tx_threshold(tx_threshold), - .tx_empty(tx_empty), - .tx_full(tx_full), - .tx_level_below(tx_level_below), - .tx_level(tx_level), - .ss(ss), - .enable(enable), - .done(done), - .busy(busy), - .miso(miso), - .mosi(mosi), - .csb(csb), - .sclk(sclk) - ); - - assign HRDATA = - (last_HADDR[`AHBL_AW-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : - (last_HADDR[`AHBL_AW-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : - (last_HADDR[`AHBL_AW-1:0] == CFG_REG_OFFSET) ? CFG_REG : - (last_HADDR[`AHBL_AW-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : - (last_HADDR[`AHBL_AW-1:0] == PR_REG_OFFSET) ? PR_REG : - (last_HADDR[`AHBL_AW-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : - (last_HADDR[`AHBL_AW-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : - (last_HADDR[`AHBL_AW-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : - (last_HADDR[`AHBL_AW-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : - (last_HADDR[`AHBL_AW-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : - (last_HADDR[`AHBL_AW-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : - (last_HADDR[`AHBL_AW-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : - (last_HADDR[`AHBL_AW-1:0] == IM_REG_OFFSET) ? IM_REG : - (last_HADDR[`AHBL_AW-1:0] == MIS_REG_OFFSET) ? MIS_REG : - (last_HADDR[`AHBL_AW-1:0] == RIS_REG_OFFSET) ? RIS_REG : - (last_HADDR[`AHBL_AW-1:0] == IC_REG_OFFSET) ? IC_REG : - (last_HADDR[`AHBL_AW-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : + localparam RXDATA_REG_OFFSET = 16'h0000; + localparam TXDATA_REG_OFFSET = 16'h0004; + localparam CFG_REG_OFFSET = 16'h0008; + localparam CTRL_REG_OFFSET = 16'h000C; + localparam PR_REG_OFFSET = 16'h0010; + localparam STATUS_REG_OFFSET = 16'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = 16'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = 16'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = 16'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = 16'hFE18; + localparam IM_REG_OFFSET = 16'hFF00; + localparam MIS_REG_OFFSET = 16'hFF04; + localparam RIS_REG_OFFSET = 16'hFF08; + localparam IC_REG_OFFSET = 16'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell ( + + + + // USE_POWER_PINS + .clk(HCLK), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = HRESETn; + + + reg last_HSEL, last_HWRITE; + reg [31:0] last_HADDR; + reg [ 1:0] last_HTRANS; + always @(posedge HCLK or negedge HRESETn) begin + if (~HRESETn) begin + last_HSEL <= 1'b0; + last_HADDR <= 1'b0; + last_HWRITE <= 1'b0; + last_HTRANS <= 1'b0; + end else if (HREADY) begin + last_HSEL <= HSEL; + last_HADDR <= HADDR; + last_HWRITE <= HWRITE; + last_HTRANS <= HTRANS; + end + end + wire ahbl_valid = last_HSEL & last_HTRANS[1]; + wire ahbl_we = last_HWRITE & ahbl_valid; + wire ahbl_re = ~last_HWRITE & ahbl_valid; + + wire [1-1:0] CPOL; + wire [1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [1-1:0] wr; + wire [1-1:0] rd; + wire [8-1:0] datai; + wire [8-1:0] datao; + wire [1-1:0] rx_en; + wire [1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [1-1:0] rx_empty; + wire [1-1:0] rx_full; + wire [1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [1-1:0] tx_empty; + wire [1-1:0] tx_full; + wire [1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [1-1:0] ss; + wire [1-1:0] enable; + wire [1-1:0] done; + wire [1-1:0] busy; + + // Register Definitions + wire [8-1:0] RXDATA_WIRE; + + wire [8-1:0] TXDATA_WIRE; + + reg [1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) CFG_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == CFG_REG_OFFSET)) CFG_REG <= HWDATA[2-1:0]; + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) CTRL_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == CTRL_REG_OFFSET)) CTRL_REG <= HWDATA[3-1:0]; + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) PR_REG <= 'h2; + else if (ahbl_we & (last_HADDR[16-1:0] == PR_REG_OFFSET)) PR_REG <= HWDATA[CDW-1:0]; + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) RX_FIFO_THRESHOLD_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET)) + RX_FIFO_THRESHOLD_REG <= HWDATA[FAW-1:0]; + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) RX_FIFO_FLUSH_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET)) + RX_FIFO_FLUSH_REG <= HWDATA[1-1:0]; + else RX_FIFO_FLUSH_REG <= 1'h0 & RX_FIFO_FLUSH_REG; + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) TX_FIFO_THRESHOLD_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET)) + TX_FIFO_THRESHOLD_REG <= HWDATA[FAW-1:0]; + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) TX_FIFO_FLUSH_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET)) + TX_FIFO_FLUSH_REG <= HWDATA[1-1:0]; + else TX_FIFO_FLUSH_REG <= 1'h0 & TX_FIFO_FLUSH_REG; + + localparam GCLK_REG_OFFSET = 16'hFF10; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) GCLK_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == GCLK_REG_OFFSET)) GCLK_REG <= HWDATA[1-1:0]; + + reg [ 5:0] IM_REG; + reg [ 5:0] IC_REG; + reg [ 5:0] RIS_REG; + + wire [6-1:0] MIS_REG = RIS_REG & IM_REG; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) IM_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == IM_REG_OFFSET)) IM_REG <= HWDATA[6-1:0]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) IC_REG <= 6'b0; + else if (ahbl_we & (last_HADDR[16-1:0] == IC_REG_OFFSET)) IC_REG <= HWDATA[6-1:0]; + else IC_REG <= 6'd0; + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) RIS_REG <= 0; + else begin + for (_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXE[_i_-0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXF[_i_-1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXE[_i_-2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXF[_i_-3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXB[_i_-4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXA[_i_-5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign HRDATA = + (last_HADDR[16-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (last_HADDR[16-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (last_HADDR[16-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (last_HADDR[16-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (last_HADDR[16-1:0] == PR_REG_OFFSET) ? PR_REG : + (last_HADDR[16-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (last_HADDR[16-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (last_HADDR[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (last_HADDR[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (last_HADDR[16-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (last_HADDR[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (last_HADDR[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (last_HADDR[16-1:0] == IM_REG_OFFSET) ? IM_REG : + (last_HADDR[16-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (last_HADDR[16-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (last_HADDR[16-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : 32'hDEADBEEF; - assign HREADYOUT = 1'b1; + assign HREADYOUT = 1'b1; - assign RXDATA_WIRE = datao; - assign rd = (ahbl_re & (last_HADDR[`AHBL_AW-1:0] == RXDATA_REG_OFFSET)); - assign datai = HWDATA; - assign wr = (ahbl_we & (last_HADDR[`AHBL_AW-1:0] == TXDATA_REG_OFFSET)); + assign RXDATA_WIRE = datao; + assign rd = (ahbl_re & (last_HADDR[16-1:0] == RXDATA_REG_OFFSET)); + assign datai = HWDATA; + assign wr = (ahbl_we & (last_HADDR[16-1:0] == TXDATA_REG_OFFSET)); endmodule diff --git a/hdl/rtl/bus_wrappers/EF_SPI_APB.dev.v b/hdl/rtl/bus_wrappers/EF_SPI_APB.dev.v new file mode 100644 index 0000000..558f5d3 --- /dev/null +++ b/hdl/rtl/bus_wrappers/EF_SPI_APB.dev.v @@ -0,0 +1,263 @@ +/* + Copyright 2024 Efabless Corp. + + Author: Efabless Corp. (ip_admin@efabless.com) + + 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. + +*/ + +/* THIS FILE IS GENERATED, DO NOT EDIT */ + +`timescale 1ns/1ps +`default_nettype none + +`define APB_AW 16 + +`include "apb_wrapper.vh" + +module EF_SPI_APB #( + parameter + CDW = 8, + FAW = 4 +) ( +`ifdef USE_POWER_PINS + inout VPWR, + inout VGND, +`endif + `APB_SLAVE_PORTS, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk +); + + localparam RXDATA_REG_OFFSET = `APB_AW'h0000; + localparam TXDATA_REG_OFFSET = `APB_AW'h0004; + localparam CFG_REG_OFFSET = `APB_AW'h0008; + localparam CTRL_REG_OFFSET = `APB_AW'h000C; + localparam PR_REG_OFFSET = `APB_AW'h0010; + localparam STATUS_REG_OFFSET = `APB_AW'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = `APB_AW'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = `APB_AW'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = `APB_AW'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = `APB_AW'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = `APB_AW'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = `APB_AW'hFE18; + localparam IM_REG_OFFSET = `APB_AW'hFF00; + localparam MIS_REG_OFFSET = `APB_AW'hFF04; + localparam RIS_REG_OFFSET = `APB_AW'hFF08; + localparam IC_REG_OFFSET = `APB_AW'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell( + `ifdef USE_POWER_PINS + .vpwr(VPWR), + .vgnd(VGND), + `endif // USE_POWER_PINS + .clk(PCLK), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = PRESETn; + + + `APB_CTRL_SIGNALS + + wire [1-1:0] CPOL; + wire [1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [1-1:0] wr; + wire [1-1:0] rd; + wire [8-1:0] datai; + wire [8-1:0] datao; + wire [1-1:0] rx_en; + wire [1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [1-1:0] rx_empty; + wire [1-1:0] rx_full; + wire [1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [1-1:0] tx_empty; + wire [1-1:0] tx_full; + wire [1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [1-1:0] ss; + wire [1-1:0] enable; + wire [1-1:0] done; + wire [1-1:0] busy; + + // Register Definitions + wire [8-1:0] RXDATA_WIRE; + + wire [8-1:0] TXDATA_WIRE; + + reg [1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + `APB_REG(CFG_REG, 0, 2) + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + `APB_REG(CTRL_REG, 0, 3) + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + `APB_REG(PR_REG, 'h2, CDW) + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `APB_REG(RX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + `APB_REG_AC(RX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `APB_REG(TX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + `APB_REG_AC(TX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + localparam GCLK_REG_OFFSET = `APB_AW'hFF10; + `APB_REG(GCLK_REG, 0, 1) + + reg [5:0] IM_REG; + reg [5:0] IC_REG; + reg [5:0] RIS_REG; + + `APB_MIS_REG(6) + `APB_REG(IM_REG, 0, 6) + `APB_IC_REG(6) + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + `APB_BLOCK(RIS_REG, 0) else begin + for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign PRDATA = + (PADDR[`APB_AW-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (PADDR[`APB_AW-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (PADDR[`APB_AW-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (PADDR[`APB_AW-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (PADDR[`APB_AW-1:0] == PR_REG_OFFSET) ? PR_REG : + (PADDR[`APB_AW-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (PADDR[`APB_AW-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (PADDR[`APB_AW-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (PADDR[`APB_AW-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (PADDR[`APB_AW-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (PADDR[`APB_AW-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (PADDR[`APB_AW-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (PADDR[`APB_AW-1:0] == IM_REG_OFFSET) ? IM_REG : + (PADDR[`APB_AW-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (PADDR[`APB_AW-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (PADDR[`APB_AW-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : + 32'hDEADBEEF; + + assign PREADY = 1'b1; + + assign RXDATA_WIRE = datao; + assign rd = (apb_re & (PADDR[`APB_AW-1:0] == RXDATA_REG_OFFSET)); + assign datai = PWDATA; + assign wr = (apb_we & (PADDR[`APB_AW-1:0] == TXDATA_REG_OFFSET)); +endmodule diff --git a/hdl/rtl/bus_wrappers/EF_SPI_APB.pp.v b/hdl/rtl/bus_wrappers/EF_SPI_APB.pp.v deleted file mode 100644 index 3c929a9..0000000 --- a/hdl/rtl/bus_wrappers/EF_SPI_APB.pp.v +++ /dev/null @@ -1,372 +0,0 @@ -/* - Copyright 2024 Efabless Corp. - - Author: Mohamed Shalan (mshalan@efabless.com) - - 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. - -*/ - -/* THIS FILE IS GENERATED, DO NOT EDIT */ - -`timescale 1ns/1ps -`default_nettype none - - - -/* - Copyright 2020 AUCOHL - - Author: Mohamed Shalan (mshalan@aucegypt.edu) - - 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. -*/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -module EF_SPI_APB #( - parameter - CDW = 8, - FAW = 4 -) ( - - - - - input wire PCLK, - input wire PRESETn, - input wire PWRITE, - input wire [31:0] PWDATA, - input wire [31:0] PADDR, - input wire PENABLE, - input wire PSEL, - output wire PREADY, - output wire [31:0] PRDATA, - output wire IRQ -, - input wire [1-1:0] miso, - output wire [1-1:0] mosi, - output wire [1-1:0] csb, - output wire [1-1:0] sclk -); - - localparam RXDATA_REG_OFFSET = 16'h0000; - localparam TXDATA_REG_OFFSET = 16'h0004; - localparam CFG_REG_OFFSET = 16'h0008; - localparam CTRL_REG_OFFSET = 16'h000C; - localparam PR_REG_OFFSET = 16'h0010; - localparam STATUS_REG_OFFSET = 16'h0014; - localparam RX_FIFO_LEVEL_REG_OFFSET = 16'hFE00; - localparam RX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE04; - localparam RX_FIFO_FLUSH_REG_OFFSET = 16'hFE08; - localparam TX_FIFO_LEVEL_REG_OFFSET = 16'hFE10; - localparam TX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE14; - localparam TX_FIFO_FLUSH_REG_OFFSET = 16'hFE18; - localparam IM_REG_OFFSET = 16'hFF00; - localparam MIS_REG_OFFSET = 16'hFF04; - localparam RIS_REG_OFFSET = 16'hFF08; - localparam IC_REG_OFFSET = 16'hFF0C; - - reg [0:0] GCLK_REG; - wire clk_g; - wire clk_gated_en = GCLK_REG[0]; - ef_gating_cell clk_gate_cell( - - - - // USE_POWER_PINS - .clk(PCLK), - .clk_en(clk_gated_en), - .clk_o(clk_g) - ); - - wire clk = clk_g; - wire rst_n = PRESETn; - - - wire apb_valid = PSEL & PENABLE; - wire apb_we = PWRITE & apb_valid; - wire apb_re = ~PWRITE & apb_valid; - - wire [1-1:0] CPOL; - wire [1-1:0] CPHA; - wire [CDW-1:0] clk_divider; - wire [1-1:0] wr; - wire [1-1:0] rd; - wire [8-1:0] datai; - wire [8-1:0] datao; - wire [1-1:0] rx_en; - wire [1-1:0] rx_flush; - wire [FAW-1:0] rx_threshold; - wire [1-1:0] rx_empty; - wire [1-1:0] rx_full; - wire [1-1:0] rx_level_above; - wire [FAW-1:0] rx_level; - wire [1-1:0] tx_flush; - wire [FAW-1:0] tx_threshold; - wire [1-1:0] tx_empty; - wire [1-1:0] tx_full; - wire [1-1:0] tx_level_below; - wire [FAW-1:0] tx_level; - wire [1-1:0] ss; - wire [1-1:0] enable; - wire [1-1:0] done; - wire [1-1:0] busy; - - // Register Definitions - wire [8-1:0] RXDATA_WIRE; - - wire [8-1:0] TXDATA_WIRE; - - reg [1:0] CFG_REG; - assign CPOL = CFG_REG[0 : 0]; - assign CPHA = CFG_REG[1 : 1]; - always @(posedge PCLK or negedge PRESETn) if(~PRESETn) CFG_REG <= 0; - else if(apb_we & (PADDR[16-1:0]==CFG_REG_OFFSET)) - CFG_REG <= PWDATA[2-1:0]; - - reg [2:0] CTRL_REG; - assign ss = CTRL_REG[0 : 0]; - assign enable = CTRL_REG[1 : 1]; - assign rx_en = CTRL_REG[2 : 2]; - always @(posedge PCLK or negedge PRESETn) if(~PRESETn) CTRL_REG <= 0; - else if(apb_we & (PADDR[16-1:0]==CTRL_REG_OFFSET)) - CTRL_REG <= PWDATA[3-1:0]; - - reg [CDW-1:0] PR_REG; - assign clk_divider = PR_REG; - always @(posedge PCLK or negedge PRESETn) if(~PRESETn) PR_REG <= 'h2; - else if(apb_we & (PADDR[16-1:0]==PR_REG_OFFSET)) - PR_REG <= PWDATA[CDW-1:0]; - - wire [8-1:0] STATUS_WIRE; - assign STATUS_WIRE[0 : 0] = tx_empty; - assign STATUS_WIRE[1 : 1] = tx_full; - assign STATUS_WIRE[2 : 2] = rx_empty; - assign STATUS_WIRE[3 : 3] = rx_full; - assign STATUS_WIRE[4 : 4] = tx_level_below; - assign STATUS_WIRE[5 : 5] = rx_level_above; - assign STATUS_WIRE[6 : 6] = busy; - assign STATUS_WIRE[7 : 7] = done; - - wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; - assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; - - reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; - assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - always @(posedge PCLK or negedge PRESETn) if(~PRESETn) RX_FIFO_THRESHOLD_REG <= 0; - else if(apb_we & (PADDR[16-1:0]==RX_FIFO_THRESHOLD_REG_OFFSET)) - RX_FIFO_THRESHOLD_REG <= PWDATA[FAW-1:0]; - - reg [0:0] RX_FIFO_FLUSH_REG; - assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; - always @(posedge PCLK or negedge PRESETn) if(~PRESETn) RX_FIFO_FLUSH_REG <= 0; - else if(apb_we & (PADDR[16-1:0]==RX_FIFO_FLUSH_REG_OFFSET)) - RX_FIFO_FLUSH_REG <= PWDATA[1-1:0]; - else - RX_FIFO_FLUSH_REG <= 1'h0 & RX_FIFO_FLUSH_REG; - - wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; - assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; - - reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; - assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - always @(posedge PCLK or negedge PRESETn) if(~PRESETn) TX_FIFO_THRESHOLD_REG <= 0; - else if(apb_we & (PADDR[16-1:0]==TX_FIFO_THRESHOLD_REG_OFFSET)) - TX_FIFO_THRESHOLD_REG <= PWDATA[FAW-1:0]; - - reg [0:0] TX_FIFO_FLUSH_REG; - assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; - always @(posedge PCLK or negedge PRESETn) if(~PRESETn) TX_FIFO_FLUSH_REG <= 0; - else if(apb_we & (PADDR[16-1:0]==TX_FIFO_FLUSH_REG_OFFSET)) - TX_FIFO_FLUSH_REG <= PWDATA[1-1:0]; - else - TX_FIFO_FLUSH_REG <= 1'h0 & TX_FIFO_FLUSH_REG; - - localparam GCLK_REG_OFFSET = 16'hFF10; - always @(posedge PCLK or negedge PRESETn) if(~PRESETn) GCLK_REG <= 0; - else if(apb_we & (PADDR[16-1:0]==GCLK_REG_OFFSET)) - GCLK_REG <= PWDATA[1-1:0]; - - reg [5:0] IM_REG; - reg [5:0] IC_REG; - reg [5:0] RIS_REG; - - wire[6-1:0] MIS_REG = RIS_REG & IM_REG; - always @(posedge PCLK or negedge PRESETn) if(~PRESETn) IM_REG <= 0; - else if(apb_we & (PADDR[16-1:0]==IM_REG_OFFSET)) - IM_REG <= PWDATA[6-1:0]; - always @(posedge PCLK or negedge PRESETn) if(~PRESETn) IC_REG <= 6'b0; - else if(apb_we & (PADDR[16-1:0]==IC_REG_OFFSET)) - IC_REG <= PWDATA[6-1:0]; - else - IC_REG <= 6'd0; - - wire [0:0] TXE = tx_empty; - wire [0:0] TXF = tx_full; - wire [0:0] RXE = rx_empty; - wire [0:0] RXF = rx_full; - wire [0:0] TXB = tx_level_below; - wire [0:0] RXA = rx_level_above; - - - integer _i_; - always @(posedge PCLK or negedge PRESETn) if(~PRESETn) RIS_REG <= 0; else begin - for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - end - - assign IRQ = |MIS_REG; - - EF_SPI #( - .CDW(CDW), - .FAW(FAW) - ) instance_to_wrap ( - .clk(clk), - .rst_n(rst_n), - .CPOL(CPOL), - .CPHA(CPHA), - .clk_divider(clk_divider), - .wr(wr), - .rd(rd), - .datai(datai), - .datao(datao), - .rx_en(rx_en), - .rx_flush(rx_flush), - .rx_threshold(rx_threshold), - .rx_empty(rx_empty), - .rx_full(rx_full), - .rx_level_above(rx_level_above), - .rx_level(rx_level), - .tx_flush(tx_flush), - .tx_threshold(tx_threshold), - .tx_empty(tx_empty), - .tx_full(tx_full), - .tx_level_below(tx_level_below), - .tx_level(tx_level), - .ss(ss), - .enable(enable), - .done(done), - .busy(busy), - .miso(miso), - .mosi(mosi), - .csb(csb), - .sclk(sclk) - ); - - assign PRDATA = - (PADDR[16-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : - (PADDR[16-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : - (PADDR[16-1:0] == CFG_REG_OFFSET) ? CFG_REG : - (PADDR[16-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : - (PADDR[16-1:0] == PR_REG_OFFSET) ? PR_REG : - (PADDR[16-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : - (PADDR[16-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : - (PADDR[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : - (PADDR[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : - (PADDR[16-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : - (PADDR[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : - (PADDR[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : - (PADDR[16-1:0] == IM_REG_OFFSET) ? IM_REG : - (PADDR[16-1:0] == MIS_REG_OFFSET) ? MIS_REG : - (PADDR[16-1:0] == RIS_REG_OFFSET) ? RIS_REG : - (PADDR[16-1:0] == IC_REG_OFFSET) ? IC_REG : - (PADDR[16-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : - 32'hDEADBEEF; - - assign PREADY = 1'b1; - - assign RXDATA_WIRE = datao; - assign rd = (apb_re & (PADDR[16-1:0] == RXDATA_REG_OFFSET)); - assign datai = PWDATA; - assign wr = (apb_we & (PADDR[16-1:0] == TXDATA_REG_OFFSET)); -endmodule diff --git a/hdl/rtl/bus_wrappers/EF_SPI_APB.v b/hdl/rtl/bus_wrappers/EF_SPI_APB.v index 54e83c6..edc34ee 100644 --- a/hdl/rtl/bus_wrappers/EF_SPI_APB.v +++ b/hdl/rtl/bus_wrappers/EF_SPI_APB.v @@ -1,7 +1,7 @@ /* Copyright 2024 Efabless Corp. - Author: Mohamed Shalan (mshalan@efabless.com) + Author: Efabless Corp. (ip_admin@efabless.com) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,245 +19,362 @@ /* THIS FILE IS GENERATED, DO NOT EDIT */ -`timescale 1ns/1ps -`default_nettype none +`timescale 1ns / 1ps `default_nettype none -`define APB_AW 16 -`include "apb_wrapper.vh" -module EF_SPI_APB #( - parameter - CDW = 8, - FAW = 4 + + + + + + + + + + + + + + + + + + +// PRINT_LICENSE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +module EF_SPI_APB #( + parameter CDW = 8, + FAW = 4 ) ( -`ifdef USE_POWER_PINS - inout VPWR, - inout VGND, -`endif - `APB_SLAVE_PORTS, - input wire [1-1:0] miso, - output wire [1-1:0] mosi, - output wire [1-1:0] csb, - output wire [1-1:0] sclk + + + + + input wire PCLK, + input wire PRESETn, + input wire PWRITE, + input wire [ 31:0] PWDATA, + input wire [ 31:0] PADDR, + input wire PENABLE, + input wire PSEL, + output wire PREADY, + output wire [ 31:0] PRDATA, + output wire IRQ, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk ); - localparam RXDATA_REG_OFFSET = `APB_AW'h0000; - localparam TXDATA_REG_OFFSET = `APB_AW'h0004; - localparam CFG_REG_OFFSET = `APB_AW'h0008; - localparam CTRL_REG_OFFSET = `APB_AW'h000C; - localparam PR_REG_OFFSET = `APB_AW'h0010; - localparam STATUS_REG_OFFSET = `APB_AW'h0014; - localparam RX_FIFO_LEVEL_REG_OFFSET = `APB_AW'hFE00; - localparam RX_FIFO_THRESHOLD_REG_OFFSET = `APB_AW'hFE04; - localparam RX_FIFO_FLUSH_REG_OFFSET = `APB_AW'hFE08; - localparam TX_FIFO_LEVEL_REG_OFFSET = `APB_AW'hFE10; - localparam TX_FIFO_THRESHOLD_REG_OFFSET = `APB_AW'hFE14; - localparam TX_FIFO_FLUSH_REG_OFFSET = `APB_AW'hFE18; - localparam IM_REG_OFFSET = `APB_AW'hFF00; - localparam MIS_REG_OFFSET = `APB_AW'hFF04; - localparam RIS_REG_OFFSET = `APB_AW'hFF08; - localparam IC_REG_OFFSET = `APB_AW'hFF0C; - - reg [0:0] GCLK_REG; - wire clk_g; - wire clk_gated_en = GCLK_REG[0]; - ef_gating_cell clk_gate_cell( - `ifdef USE_POWER_PINS - .vpwr(VPWR), - .vgnd(VGND), - `endif // USE_POWER_PINS - .clk(PCLK), - .clk_en(clk_gated_en), - .clk_o(clk_g) - ); - - wire clk = clk_g; - wire rst_n = PRESETn; - - - `APB_CTRL_SIGNALS - - wire [1-1:0] CPOL; - wire [1-1:0] CPHA; - wire [CDW-1:0] clk_divider; - wire [1-1:0] wr; - wire [1-1:0] rd; - wire [8-1:0] datai; - wire [8-1:0] datao; - wire [1-1:0] rx_en; - wire [1-1:0] rx_flush; - wire [FAW-1:0] rx_threshold; - wire [1-1:0] rx_empty; - wire [1-1:0] rx_full; - wire [1-1:0] rx_level_above; - wire [FAW-1:0] rx_level; - wire [1-1:0] tx_flush; - wire [FAW-1:0] tx_threshold; - wire [1-1:0] tx_empty; - wire [1-1:0] tx_full; - wire [1-1:0] tx_level_below; - wire [FAW-1:0] tx_level; - wire [1-1:0] ss; - wire [1-1:0] enable; - wire [1-1:0] done; - wire [1-1:0] busy; - - // Register Definitions - wire [8-1:0] RXDATA_WIRE; - - wire [8-1:0] TXDATA_WIRE; - - reg [1:0] CFG_REG; - assign CPOL = CFG_REG[0 : 0]; - assign CPHA = CFG_REG[1 : 1]; - `APB_REG(CFG_REG, 0, 2) - - reg [2:0] CTRL_REG; - assign ss = CTRL_REG[0 : 0]; - assign enable = CTRL_REG[1 : 1]; - assign rx_en = CTRL_REG[2 : 2]; - `APB_REG(CTRL_REG, 0, 3) - - reg [CDW-1:0] PR_REG; - assign clk_divider = PR_REG; - `APB_REG(PR_REG, 'h2, CDW) - - wire [8-1:0] STATUS_WIRE; - assign STATUS_WIRE[0 : 0] = tx_empty; - assign STATUS_WIRE[1 : 1] = tx_full; - assign STATUS_WIRE[2 : 2] = rx_empty; - assign STATUS_WIRE[3 : 3] = rx_full; - assign STATUS_WIRE[4 : 4] = tx_level_below; - assign STATUS_WIRE[5 : 5] = rx_level_above; - assign STATUS_WIRE[6 : 6] = busy; - assign STATUS_WIRE[7 : 7] = done; - - wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; - assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; - - reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; - assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - `APB_REG(RX_FIFO_THRESHOLD_REG, 0, FAW) - - reg [0:0] RX_FIFO_FLUSH_REG; - assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; - `APB_REG_AC(RX_FIFO_FLUSH_REG, 0, 1, 1'h0) - - wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; - assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; - - reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; - assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - `APB_REG(TX_FIFO_THRESHOLD_REG, 0, FAW) - - reg [0:0] TX_FIFO_FLUSH_REG; - assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; - `APB_REG_AC(TX_FIFO_FLUSH_REG, 0, 1, 1'h0) - - localparam GCLK_REG_OFFSET = `APB_AW'hFF10; - `APB_REG(GCLK_REG, 0, 1) - - reg [5:0] IM_REG; - reg [5:0] IC_REG; - reg [5:0] RIS_REG; - - `APB_MIS_REG(6) - `APB_REG(IM_REG, 0, 6) - `APB_IC_REG(6) - - wire [0:0] TXE = tx_empty; - wire [0:0] TXF = tx_full; - wire [0:0] RXE = rx_empty; - wire [0:0] RXF = rx_full; - wire [0:0] TXB = tx_level_below; - wire [0:0] RXA = rx_level_above; - - - integer _i_; - `APB_BLOCK(RIS_REG, 0) else begin - for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - end - - assign IRQ = |MIS_REG; - - EF_SPI #( - .CDW(CDW), - .FAW(FAW) - ) instance_to_wrap ( - .clk(clk), - .rst_n(rst_n), - .CPOL(CPOL), - .CPHA(CPHA), - .clk_divider(clk_divider), - .wr(wr), - .rd(rd), - .datai(datai), - .datao(datao), - .rx_en(rx_en), - .rx_flush(rx_flush), - .rx_threshold(rx_threshold), - .rx_empty(rx_empty), - .rx_full(rx_full), - .rx_level_above(rx_level_above), - .rx_level(rx_level), - .tx_flush(tx_flush), - .tx_threshold(tx_threshold), - .tx_empty(tx_empty), - .tx_full(tx_full), - .tx_level_below(tx_level_below), - .tx_level(tx_level), - .ss(ss), - .enable(enable), - .done(done), - .busy(busy), - .miso(miso), - .mosi(mosi), - .csb(csb), - .sclk(sclk) - ); - - assign PRDATA = - (PADDR[`APB_AW-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : - (PADDR[`APB_AW-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : - (PADDR[`APB_AW-1:0] == CFG_REG_OFFSET) ? CFG_REG : - (PADDR[`APB_AW-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : - (PADDR[`APB_AW-1:0] == PR_REG_OFFSET) ? PR_REG : - (PADDR[`APB_AW-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : - (PADDR[`APB_AW-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : - (PADDR[`APB_AW-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : - (PADDR[`APB_AW-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : - (PADDR[`APB_AW-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : - (PADDR[`APB_AW-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : - (PADDR[`APB_AW-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : - (PADDR[`APB_AW-1:0] == IM_REG_OFFSET) ? IM_REG : - (PADDR[`APB_AW-1:0] == MIS_REG_OFFSET) ? MIS_REG : - (PADDR[`APB_AW-1:0] == RIS_REG_OFFSET) ? RIS_REG : - (PADDR[`APB_AW-1:0] == IC_REG_OFFSET) ? IC_REG : - (PADDR[`APB_AW-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : + localparam RXDATA_REG_OFFSET = 16'h0000; + localparam TXDATA_REG_OFFSET = 16'h0004; + localparam CFG_REG_OFFSET = 16'h0008; + localparam CTRL_REG_OFFSET = 16'h000C; + localparam PR_REG_OFFSET = 16'h0010; + localparam STATUS_REG_OFFSET = 16'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = 16'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = 16'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = 16'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = 16'hFE18; + localparam IM_REG_OFFSET = 16'hFF00; + localparam MIS_REG_OFFSET = 16'hFF04; + localparam RIS_REG_OFFSET = 16'hFF08; + localparam IC_REG_OFFSET = 16'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell ( + + + + // USE_POWER_PINS + .clk(PCLK), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = PRESETn; + + + wire apb_valid = PSEL & PENABLE; + wire apb_we = PWRITE & apb_valid; + wire apb_re = ~PWRITE & apb_valid; + + wire [ 1-1:0] CPOL; + wire [ 1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [ 1-1:0] wr; + wire [ 1-1:0] rd; + wire [ 8-1:0] datai; + wire [ 8-1:0] datao; + wire [ 1-1:0] rx_en; + wire [ 1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [ 1-1:0] rx_empty; + wire [ 1-1:0] rx_full; + wire [ 1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [ 1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [ 1-1:0] tx_empty; + wire [ 1-1:0] tx_full; + wire [ 1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [ 1-1:0] ss; + wire [ 1-1:0] enable; + wire [ 1-1:0] done; + wire [ 1-1:0] busy; + + // Register Definitions + wire [ 8-1:0] RXDATA_WIRE; + + wire [ 8-1:0] TXDATA_WIRE; + + reg [ 1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) CFG_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == CFG_REG_OFFSET)) CFG_REG <= PWDATA[2-1:0]; + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) CTRL_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == CTRL_REG_OFFSET)) CTRL_REG <= PWDATA[3-1:0]; + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) PR_REG <= 'h2; + else if (apb_we & (PADDR[16-1:0] == PR_REG_OFFSET)) PR_REG <= PWDATA[CDW-1:0]; + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) RX_FIFO_THRESHOLD_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET)) + RX_FIFO_THRESHOLD_REG <= PWDATA[FAW-1:0]; + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) RX_FIFO_FLUSH_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET)) + RX_FIFO_FLUSH_REG <= PWDATA[1-1:0]; + else RX_FIFO_FLUSH_REG <= 1'h0 & RX_FIFO_FLUSH_REG; + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) TX_FIFO_THRESHOLD_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET)) + TX_FIFO_THRESHOLD_REG <= PWDATA[FAW-1:0]; + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) TX_FIFO_FLUSH_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET)) + TX_FIFO_FLUSH_REG <= PWDATA[1-1:0]; + else TX_FIFO_FLUSH_REG <= 1'h0 & TX_FIFO_FLUSH_REG; + + localparam GCLK_REG_OFFSET = 16'hFF10; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) GCLK_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == GCLK_REG_OFFSET)) GCLK_REG <= PWDATA[1-1:0]; + + reg [ 5:0] IM_REG; + reg [ 5:0] IC_REG; + reg [ 5:0] RIS_REG; + + wire [6-1:0] MIS_REG = RIS_REG & IM_REG; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) IM_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == IM_REG_OFFSET)) IM_REG <= PWDATA[6-1:0]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) IC_REG <= 6'b0; + else if (apb_we & (PADDR[16-1:0] == IC_REG_OFFSET)) IC_REG <= PWDATA[6-1:0]; + else IC_REG <= 6'd0; + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) RIS_REG <= 0; + else begin + for (_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXE[_i_-0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXF[_i_-1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXE[_i_-2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXF[_i_-3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXB[_i_-4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXA[_i_-5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign PRDATA = + (PADDR[16-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (PADDR[16-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (PADDR[16-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (PADDR[16-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (PADDR[16-1:0] == PR_REG_OFFSET) ? PR_REG : + (PADDR[16-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (PADDR[16-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (PADDR[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (PADDR[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (PADDR[16-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (PADDR[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (PADDR[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (PADDR[16-1:0] == IM_REG_OFFSET) ? IM_REG : + (PADDR[16-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (PADDR[16-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (PADDR[16-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : 32'hDEADBEEF; - assign PREADY = 1'b1; + assign PREADY = 1'b1; - assign RXDATA_WIRE = datao; - assign rd = (apb_re & (PADDR[`APB_AW-1:0] == RXDATA_REG_OFFSET)); - assign datai = PWDATA; - assign wr = (apb_we & (PADDR[`APB_AW-1:0] == TXDATA_REG_OFFSET)); + assign RXDATA_WIRE = datao; + assign rd = (apb_re & (PADDR[16-1:0] == RXDATA_REG_OFFSET)); + assign datai = PWDATA; + assign wr = (apb_we & (PADDR[16-1:0] == TXDATA_REG_OFFSET)); endmodule diff --git a/hdl/rtl/bus_wrappers/EF_SPI_WB.dev.v b/hdl/rtl/bus_wrappers/EF_SPI_WB.dev.v new file mode 100644 index 0000000..7e4df56 --- /dev/null +++ b/hdl/rtl/bus_wrappers/EF_SPI_WB.dev.v @@ -0,0 +1,268 @@ +/* + Copyright 2024 Efabless Corp. + + Author: Efabless Corp. (ip_admin@efabless.com) + + 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. + +*/ + +/* THIS FILE IS GENERATED, DO NOT EDIT */ + +`timescale 1ns/1ps +`default_nettype none + +`define WB_AW 16 + +`include "wb_wrapper.vh" + +module EF_SPI_WB #( + parameter + CDW = 8, + FAW = 4 +) ( +`ifdef USE_POWER_PINS + inout VPWR, + inout VGND, +`endif + `WB_SLAVE_PORTS, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk +); + + localparam RXDATA_REG_OFFSET = `WB_AW'h0000; + localparam TXDATA_REG_OFFSET = `WB_AW'h0004; + localparam CFG_REG_OFFSET = `WB_AW'h0008; + localparam CTRL_REG_OFFSET = `WB_AW'h000C; + localparam PR_REG_OFFSET = `WB_AW'h0010; + localparam STATUS_REG_OFFSET = `WB_AW'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = `WB_AW'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = `WB_AW'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = `WB_AW'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = `WB_AW'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = `WB_AW'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = `WB_AW'hFE18; + localparam IM_REG_OFFSET = `WB_AW'hFF00; + localparam MIS_REG_OFFSET = `WB_AW'hFF04; + localparam RIS_REG_OFFSET = `WB_AW'hFF08; + localparam IC_REG_OFFSET = `WB_AW'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell( + `ifdef USE_POWER_PINS + .vpwr(VPWR), + .vgnd(VGND), + `endif // USE_POWER_PINS + .clk(clk_i), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = (~rst_i); + + + `WB_CTRL_SIGNALS + + wire [1-1:0] CPOL; + wire [1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [1-1:0] wr; + wire [1-1:0] rd; + wire [8-1:0] datai; + wire [8-1:0] datao; + wire [1-1:0] rx_en; + wire [1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [1-1:0] rx_empty; + wire [1-1:0] rx_full; + wire [1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [1-1:0] tx_empty; + wire [1-1:0] tx_full; + wire [1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [1-1:0] ss; + wire [1-1:0] enable; + wire [1-1:0] done; + wire [1-1:0] busy; + + // Register Definitions + wire [8-1:0] RXDATA_WIRE; + + wire [8-1:0] TXDATA_WIRE; + + reg [1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + `WB_REG(CFG_REG, 0, 2) + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + `WB_REG(CTRL_REG, 0, 3) + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + `WB_REG(PR_REG, 'h2, CDW) + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `WB_REG(RX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + `WB_REG_AC(RX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `WB_REG(TX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + `WB_REG_AC(TX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + localparam GCLK_REG_OFFSET = `WB_AW'hFF10; + `WB_REG(GCLK_REG, 0, 1) + + reg [5:0] IM_REG; + reg [5:0] IC_REG; + reg [5:0] RIS_REG; + + `WB_MIS_REG(6) + `WB_REG(IM_REG, 0, 6) + `WB_IC_REG(6) + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + `WB_BLOCK(RIS_REG, 0) else begin + for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign dat_o = + (adr_i[`WB_AW-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (adr_i[`WB_AW-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (adr_i[`WB_AW-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (adr_i[`WB_AW-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (adr_i[`WB_AW-1:0] == PR_REG_OFFSET) ? PR_REG : + (adr_i[`WB_AW-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (adr_i[`WB_AW-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (adr_i[`WB_AW-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (adr_i[`WB_AW-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (adr_i[`WB_AW-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (adr_i[`WB_AW-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (adr_i[`WB_AW-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (adr_i[`WB_AW-1:0] == IM_REG_OFFSET) ? IM_REG : + (adr_i[`WB_AW-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (adr_i[`WB_AW-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (adr_i[`WB_AW-1:0] == IC_REG_OFFSET) ? IC_REG : + 32'hDEADBEEF; + + always @ (posedge clk_i or posedge rst_i) + if(rst_i) + ack_o <= 1'b0; + else if(wb_valid & ~ack_o) + ack_o <= 1'b1; + else + ack_o <= 1'b0; + assign RXDATA_WIRE = datao; + assign rd = ack_o & (wb_re & (adr_i[`WB_AW-1:0] == RXDATA_REG_OFFSET)); + assign datai = dat_i; + assign wr = ack_o & (wb_we & (adr_i[`WB_AW-1:0] == TXDATA_REG_OFFSET)); +endmodule diff --git a/hdl/rtl/bus_wrappers/EF_SPI_WB.pp.v b/hdl/rtl/bus_wrappers/EF_SPI_WB.pp.v deleted file mode 100644 index aceda61..0000000 --- a/hdl/rtl/bus_wrappers/EF_SPI_WB.pp.v +++ /dev/null @@ -1,335 +0,0 @@ -/* - Copyright 2024 Efabless Corp. - - Author: Mohamed Shalan (mshalan@efabless.com) - - 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. - -*/ - -/* THIS FILE IS GENERATED, DO NOT EDIT */ - -`timescale 1ns/1ps -`default_nettype none - - - -/* - Copyright 2020 AUCOHL - - Author: Mohamed Shalan (mshalan@aucegypt.edu) - - 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. -*/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -module EF_SPI_WB #( - parameter - CDW = 8, - FAW = 4 -) ( - - - - - input wire ext_clk, - input wire clk_i, - input wire rst_i, - input wire [31:0] adr_i, - input wire [31:0] dat_i, - output wire [31:0] dat_o, - input wire [3:0] sel_i, - input wire cyc_i, - input wire stb_i, - output reg ack_o, - input wire we_i, - output wire IRQ, - input wire [1-1:0] miso, - output wire [1-1:0] mosi, - output wire [1-1:0] csb, - output wire [1-1:0] sclk -); - - localparam RXDATA_REG_OFFSET = 16'h0000; - localparam TXDATA_REG_OFFSET = 16'h0004; - localparam CFG_REG_OFFSET = 16'h0008; - localparam CTRL_REG_OFFSET = 16'h000C; - localparam PR_REG_OFFSET = 16'h0010; - localparam STATUS_REG_OFFSET = 16'h0014; - localparam RX_FIFO_LEVEL_REG_OFFSET = 16'hFE00; - localparam RX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE04; - localparam RX_FIFO_FLUSH_REG_OFFSET = 16'hFE08; - localparam TX_FIFO_LEVEL_REG_OFFSET = 16'hFE10; - localparam TX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE14; - localparam TX_FIFO_FLUSH_REG_OFFSET = 16'hFE18; - localparam IM_REG_OFFSET = 16'hFF00; - localparam MIS_REG_OFFSET = 16'hFF04; - localparam RIS_REG_OFFSET = 16'hFF08; - localparam IC_REG_OFFSET = 16'hFF0C; - - reg [0:0] GCLK_REG; - wire clk_g; - wire clk_gated_en = GCLK_REG[0]; - ef_gating_cell clk_gate_cell( - - - - // USE_POWER_PINS - .clk(clk_i), - .clk_en(clk_gated_en), - .clk_o(clk_g) - ); - - wire clk = clk_g; - wire rst_n = (~rst_i); - - - wire wb_valid = cyc_i & stb_i; - wire wb_we = we_i & wb_valid; - wire wb_re = ~we_i & wb_valid; - wire[3:0] wb_byte_sel = sel_i & {4{wb_we}}; - - wire [1-1:0] CPOL; - wire [1-1:0] CPHA; - wire [CDW-1:0] clk_divider; - wire [1-1:0] wr; - wire [1-1:0] rd; - wire [8-1:0] datai; - wire [8-1:0] datao; - wire [1-1:0] rx_en; - wire [1-1:0] rx_flush; - wire [FAW-1:0] rx_threshold; - wire [1-1:0] rx_empty; - wire [1-1:0] rx_full; - wire [1-1:0] rx_level_above; - wire [FAW-1:0] rx_level; - wire [1-1:0] tx_flush; - wire [FAW-1:0] tx_threshold; - wire [1-1:0] tx_empty; - wire [1-1:0] tx_full; - wire [1-1:0] tx_level_below; - wire [FAW-1:0] tx_level; - wire [1-1:0] ss; - wire [1-1:0] enable; - wire [1-1:0] done; - wire [1-1:0] busy; - - // Register Definitions - wire [8-1:0] RXDATA_WIRE; - - wire [8-1:0] TXDATA_WIRE; - - reg [1:0] CFG_REG; - assign CPOL = CFG_REG[0 : 0]; - assign CPHA = CFG_REG[1 : 1]; - always @(posedge clk_i or posedge rst_i) if(rst_i) CFG_REG <= 0; else if(wb_we & (adr_i[16-1:0]==CFG_REG_OFFSET)) CFG_REG <= dat_i[2-1:0]; - - reg [2:0] CTRL_REG; - assign ss = CTRL_REG[0 : 0]; - assign enable = CTRL_REG[1 : 1]; - assign rx_en = CTRL_REG[2 : 2]; - always @(posedge clk_i or posedge rst_i) if(rst_i) CTRL_REG <= 0; else if(wb_we & (adr_i[16-1:0]==CTRL_REG_OFFSET)) CTRL_REG <= dat_i[3-1:0]; - - reg [CDW-1:0] PR_REG; - assign clk_divider = PR_REG; - always @(posedge clk_i or posedge rst_i) if(rst_i) PR_REG <= 'h2; else if(wb_we & (adr_i[16-1:0]==PR_REG_OFFSET)) PR_REG <= dat_i[CDW-1:0]; - - wire [8-1:0] STATUS_WIRE; - assign STATUS_WIRE[0 : 0] = tx_empty; - assign STATUS_WIRE[1 : 1] = tx_full; - assign STATUS_WIRE[2 : 2] = rx_empty; - assign STATUS_WIRE[3 : 3] = rx_full; - assign STATUS_WIRE[4 : 4] = tx_level_below; - assign STATUS_WIRE[5 : 5] = rx_level_above; - assign STATUS_WIRE[6 : 6] = busy; - assign STATUS_WIRE[7 : 7] = done; - - wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; - assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; - - reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; - assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - always @(posedge clk_i or posedge rst_i) if(rst_i) RX_FIFO_THRESHOLD_REG <= 0; else if(wb_we & (adr_i[16-1:0]==RX_FIFO_THRESHOLD_REG_OFFSET)) RX_FIFO_THRESHOLD_REG <= dat_i[FAW-1:0]; - - reg [0:0] RX_FIFO_FLUSH_REG; - assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; - always @(posedge clk_i or posedge rst_i) if(rst_i) RX_FIFO_FLUSH_REG <= 0; else if(wb_we & (adr_i[16-1:0]==RX_FIFO_FLUSH_REG_OFFSET)) RX_FIFO_FLUSH_REG <= dat_i[1-1:0]; else RX_FIFO_FLUSH_REG <= 1'h0 & RX_FIFO_FLUSH_REG; - - wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; - assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; - - reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; - assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - always @(posedge clk_i or posedge rst_i) if(rst_i) TX_FIFO_THRESHOLD_REG <= 0; else if(wb_we & (adr_i[16-1:0]==TX_FIFO_THRESHOLD_REG_OFFSET)) TX_FIFO_THRESHOLD_REG <= dat_i[FAW-1:0]; - - reg [0:0] TX_FIFO_FLUSH_REG; - assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; - always @(posedge clk_i or posedge rst_i) if(rst_i) TX_FIFO_FLUSH_REG <= 0; else if(wb_we & (adr_i[16-1:0]==TX_FIFO_FLUSH_REG_OFFSET)) TX_FIFO_FLUSH_REG <= dat_i[1-1:0]; else TX_FIFO_FLUSH_REG <= 1'h0 & TX_FIFO_FLUSH_REG; - - localparam GCLK_REG_OFFSET = 16'hFF10; - always @(posedge clk_i or posedge rst_i) if(rst_i) GCLK_REG <= 0; else if(wb_we & (adr_i[16-1:0]==GCLK_REG_OFFSET)) GCLK_REG <= dat_i[1-1:0]; - - reg [5:0] IM_REG; - reg [5:0] IC_REG; - reg [5:0] RIS_REG; - - wire[6-1:0] MIS_REG = RIS_REG & IM_REG; - always @(posedge clk_i or posedge rst_i) if(rst_i) IM_REG <= 0; else if(wb_we & (adr_i[16-1:0]==IM_REG_OFFSET)) IM_REG <= dat_i[6-1:0]; - always @(posedge clk_i or posedge rst_i) if(rst_i) IC_REG <= 6'b0; - else if(wb_we & (adr_i[16-1:0]==IC_REG_OFFSET)) - IC_REG <= dat_i[6-1:0]; - else - IC_REG <= 6'd0; - - wire [0:0] TXE = tx_empty; - wire [0:0] TXF = tx_full; - wire [0:0] RXE = rx_empty; - wire [0:0] RXF = rx_full; - wire [0:0] TXB = tx_level_below; - wire [0:0] RXA = rx_level_above; - - - integer _i_; - always @(posedge clk_i or posedge rst_i) if(rst_i) RIS_REG <= 0; else begin - for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - end - - assign IRQ = |MIS_REG; - - EF_SPI #( - .CDW(CDW), - .FAW(FAW) - ) instance_to_wrap ( - .clk(clk), - .rst_n(rst_n), - .CPOL(CPOL), - .CPHA(CPHA), - .clk_divider(clk_divider), - .wr(wr), - .rd(rd), - .datai(datai), - .datao(datao), - .rx_en(rx_en), - .rx_flush(rx_flush), - .rx_threshold(rx_threshold), - .rx_empty(rx_empty), - .rx_full(rx_full), - .rx_level_above(rx_level_above), - .rx_level(rx_level), - .tx_flush(tx_flush), - .tx_threshold(tx_threshold), - .tx_empty(tx_empty), - .tx_full(tx_full), - .tx_level_below(tx_level_below), - .tx_level(tx_level), - .ss(ss), - .enable(enable), - .done(done), - .busy(busy), - .miso(miso), - .mosi(mosi), - .csb(csb), - .sclk(sclk) - ); - - assign dat_o = - (adr_i[16-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : - (adr_i[16-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : - (adr_i[16-1:0] == CFG_REG_OFFSET) ? CFG_REG : - (adr_i[16-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : - (adr_i[16-1:0] == PR_REG_OFFSET) ? PR_REG : - (adr_i[16-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : - (adr_i[16-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : - (adr_i[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : - (adr_i[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : - (adr_i[16-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : - (adr_i[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : - (adr_i[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : - (adr_i[16-1:0] == IM_REG_OFFSET) ? IM_REG : - (adr_i[16-1:0] == MIS_REG_OFFSET) ? MIS_REG : - (adr_i[16-1:0] == RIS_REG_OFFSET) ? RIS_REG : - (adr_i[16-1:0] == IC_REG_OFFSET) ? IC_REG : - 32'hDEADBEEF; - - always @ (posedge clk_i or posedge rst_i) - if(rst_i) - ack_o <= 1'b0; - else if(wb_valid & ~ack_o) - ack_o <= 1'b1; - else - ack_o <= 1'b0; - assign RXDATA_WIRE = datao; - assign rd = ack_o & (wb_re & (adr_i[16-1:0] == RXDATA_REG_OFFSET)); - assign datai = dat_i; - assign wr = ack_o & (wb_we & (adr_i[16-1:0] == TXDATA_REG_OFFSET)); -endmodule diff --git a/hdl/rtl/bus_wrappers/EF_SPI_WB.v b/hdl/rtl/bus_wrappers/EF_SPI_WB.v index 966bca6..fd93435 100644 --- a/hdl/rtl/bus_wrappers/EF_SPI_WB.v +++ b/hdl/rtl/bus_wrappers/EF_SPI_WB.v @@ -1,7 +1,7 @@ /* Copyright 2024 Efabless Corp. - Author: Mohamed Shalan (mshalan@efabless.com) + Author: Efabless Corp. (ip_admin@efabless.com) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,249 +19,342 @@ /* THIS FILE IS GENERATED, DO NOT EDIT */ -`timescale 1ns/1ps -`default_nettype none +`timescale 1ns / 1ps `default_nettype none -`define WB_AW 16 -`include "wb_wrapper.vh" -module EF_SPI_WB #( - parameter - CDW = 8, - FAW = 4 + + + + + + + + + + + + + + + + + + +// PRINT_LICENSE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +module EF_SPI_WB #( + parameter CDW = 8, + FAW = 4 ) ( -`ifdef USE_POWER_PINS - inout VPWR, - inout VGND, -`endif - `WB_SLAVE_PORTS, - input wire [1-1:0] miso, - output wire [1-1:0] mosi, - output wire [1-1:0] csb, - output wire [1-1:0] sclk + + + + + input wire clk_i, + input wire rst_i, + input wire [ 31:0] adr_i, + input wire [ 31:0] dat_i, + output wire [ 31:0] dat_o, + input wire [ 3:0] sel_i, + input wire cyc_i, + input wire stb_i, + output reg ack_o, + input wire we_i, + output wire IRQ, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk ); - localparam RXDATA_REG_OFFSET = `WB_AW'h0000; - localparam TXDATA_REG_OFFSET = `WB_AW'h0004; - localparam CFG_REG_OFFSET = `WB_AW'h0008; - localparam CTRL_REG_OFFSET = `WB_AW'h000C; - localparam PR_REG_OFFSET = `WB_AW'h0010; - localparam STATUS_REG_OFFSET = `WB_AW'h0014; - localparam RX_FIFO_LEVEL_REG_OFFSET = `WB_AW'hFE00; - localparam RX_FIFO_THRESHOLD_REG_OFFSET = `WB_AW'hFE04; - localparam RX_FIFO_FLUSH_REG_OFFSET = `WB_AW'hFE08; - localparam TX_FIFO_LEVEL_REG_OFFSET = `WB_AW'hFE10; - localparam TX_FIFO_THRESHOLD_REG_OFFSET = `WB_AW'hFE14; - localparam TX_FIFO_FLUSH_REG_OFFSET = `WB_AW'hFE18; - localparam IM_REG_OFFSET = `WB_AW'hFF00; - localparam MIS_REG_OFFSET = `WB_AW'hFF04; - localparam RIS_REG_OFFSET = `WB_AW'hFF08; - localparam IC_REG_OFFSET = `WB_AW'hFF0C; - - reg [0:0] GCLK_REG; - wire clk_g; - wire clk_gated_en = GCLK_REG[0]; - ef_gating_cell clk_gate_cell( - `ifdef USE_POWER_PINS - .vpwr(VPWR), - .vgnd(VGND), - `endif // USE_POWER_PINS - .clk(clk_i), - .clk_en(clk_gated_en), - .clk_o(clk_g) - ); - - wire clk = clk_g; - wire rst_n = (~rst_i); - - - `WB_CTRL_SIGNALS - - wire [1-1:0] CPOL; - wire [1-1:0] CPHA; - wire [CDW-1:0] clk_divider; - wire [1-1:0] wr; - wire [1-1:0] rd; - wire [8-1:0] datai; - wire [8-1:0] datao; - wire [1-1:0] rx_en; - wire [1-1:0] rx_flush; - wire [FAW-1:0] rx_threshold; - wire [1-1:0] rx_empty; - wire [1-1:0] rx_full; - wire [1-1:0] rx_level_above; - wire [FAW-1:0] rx_level; - wire [1-1:0] tx_flush; - wire [FAW-1:0] tx_threshold; - wire [1-1:0] tx_empty; - wire [1-1:0] tx_full; - wire [1-1:0] tx_level_below; - wire [FAW-1:0] tx_level; - wire [1-1:0] ss; - wire [1-1:0] enable; - wire [1-1:0] done; - wire [1-1:0] busy; - - // Register Definitions - wire [8-1:0] RXDATA_WIRE; - - wire [8-1:0] TXDATA_WIRE; - - reg [1:0] CFG_REG; - assign CPOL = CFG_REG[0 : 0]; - assign CPHA = CFG_REG[1 : 1]; - `WB_REG(CFG_REG, 0, 2) - - reg [2:0] CTRL_REG; - assign ss = CTRL_REG[0 : 0]; - assign enable = CTRL_REG[1 : 1]; - assign rx_en = CTRL_REG[2 : 2]; - `WB_REG(CTRL_REG, 0, 3) - - reg [CDW-1:0] PR_REG; - assign clk_divider = PR_REG; - `WB_REG(PR_REG, 'h2, CDW) - - wire [8-1:0] STATUS_WIRE; - assign STATUS_WIRE[0 : 0] = tx_empty; - assign STATUS_WIRE[1 : 1] = tx_full; - assign STATUS_WIRE[2 : 2] = rx_empty; - assign STATUS_WIRE[3 : 3] = rx_full; - assign STATUS_WIRE[4 : 4] = tx_level_below; - assign STATUS_WIRE[5 : 5] = rx_level_above; - assign STATUS_WIRE[6 : 6] = busy; - assign STATUS_WIRE[7 : 7] = done; - - wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; - assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; - - reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; - assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - `WB_REG(RX_FIFO_THRESHOLD_REG, 0, FAW) - - reg [0:0] RX_FIFO_FLUSH_REG; - assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; - `WB_REG_AC(RX_FIFO_FLUSH_REG, 0, 1, 1'h0) - - wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; - assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; - - reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; - assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; - `WB_REG(TX_FIFO_THRESHOLD_REG, 0, FAW) - - reg [0:0] TX_FIFO_FLUSH_REG; - assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; - `WB_REG_AC(TX_FIFO_FLUSH_REG, 0, 1, 1'h0) - - localparam GCLK_REG_OFFSET = `WB_AW'hFF10; - `WB_REG(GCLK_REG, 0, 1) - - reg [5:0] IM_REG; - reg [5:0] IC_REG; - reg [5:0] RIS_REG; - - `WB_MIS_REG(6) - `WB_REG(IM_REG, 0, 6) - `WB_IC_REG(6) - - wire [0:0] TXE = tx_empty; - wire [0:0] TXF = tx_full; - wire [0:0] RXE = rx_empty; - wire [0:0] RXF = rx_full; - wire [0:0] TXB = tx_level_below; - wire [0:0] RXA = rx_level_above; - - - integer _i_; - `WB_BLOCK(RIS_REG, 0) else begin - for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin - if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; - end - end - - assign IRQ = |MIS_REG; - - EF_SPI #( - .CDW(CDW), - .FAW(FAW) - ) instance_to_wrap ( - .clk(clk), - .rst_n(rst_n), - .CPOL(CPOL), - .CPHA(CPHA), - .clk_divider(clk_divider), - .wr(wr), - .rd(rd), - .datai(datai), - .datao(datao), - .rx_en(rx_en), - .rx_flush(rx_flush), - .rx_threshold(rx_threshold), - .rx_empty(rx_empty), - .rx_full(rx_full), - .rx_level_above(rx_level_above), - .rx_level(rx_level), - .tx_flush(tx_flush), - .tx_threshold(tx_threshold), - .tx_empty(tx_empty), - .tx_full(tx_full), - .tx_level_below(tx_level_below), - .tx_level(tx_level), - .ss(ss), - .enable(enable), - .done(done), - .busy(busy), - .miso(miso), - .mosi(mosi), - .csb(csb), - .sclk(sclk) - ); - - assign dat_o = - (adr_i[`WB_AW-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : - (adr_i[`WB_AW-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : - (adr_i[`WB_AW-1:0] == CFG_REG_OFFSET) ? CFG_REG : - (adr_i[`WB_AW-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : - (adr_i[`WB_AW-1:0] == PR_REG_OFFSET) ? PR_REG : - (adr_i[`WB_AW-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : - (adr_i[`WB_AW-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : - (adr_i[`WB_AW-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : - (adr_i[`WB_AW-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : - (adr_i[`WB_AW-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : - (adr_i[`WB_AW-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : - (adr_i[`WB_AW-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : - (adr_i[`WB_AW-1:0] == IM_REG_OFFSET) ? IM_REG : - (adr_i[`WB_AW-1:0] == MIS_REG_OFFSET) ? MIS_REG : - (adr_i[`WB_AW-1:0] == RIS_REG_OFFSET) ? RIS_REG : - (adr_i[`WB_AW-1:0] == IC_REG_OFFSET) ? IC_REG : + localparam RXDATA_REG_OFFSET = 16'h0000; + localparam TXDATA_REG_OFFSET = 16'h0004; + localparam CFG_REG_OFFSET = 16'h0008; + localparam CTRL_REG_OFFSET = 16'h000C; + localparam PR_REG_OFFSET = 16'h0010; + localparam STATUS_REG_OFFSET = 16'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = 16'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = 16'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = 16'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = 16'hFE18; + localparam IM_REG_OFFSET = 16'hFF00; + localparam MIS_REG_OFFSET = 16'hFF04; + localparam RIS_REG_OFFSET = 16'hFF08; + localparam IC_REG_OFFSET = 16'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell ( + + + + // USE_POWER_PINS + .clk(clk_i), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = (~rst_i); + + + wire wb_valid = cyc_i & stb_i; + wire wb_we = we_i & wb_valid; + wire wb_re = ~we_i & wb_valid; + wire [ 3:0] wb_byte_sel = sel_i & {4{wb_we}}; + + wire [ 1-1:0] CPOL; + wire [ 1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [ 1-1:0] wr; + wire [ 1-1:0] rd; + wire [ 8-1:0] datai; + wire [ 8-1:0] datao; + wire [ 1-1:0] rx_en; + wire [ 1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [ 1-1:0] rx_empty; + wire [ 1-1:0] rx_full; + wire [ 1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [ 1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [ 1-1:0] tx_empty; + wire [ 1-1:0] tx_full; + wire [ 1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [ 1-1:0] ss; + wire [ 1-1:0] enable; + wire [ 1-1:0] done; + wire [ 1-1:0] busy; + + // Register Definitions + wire [ 8-1:0] RXDATA_WIRE; + + wire [ 8-1:0] TXDATA_WIRE; + + reg [ 1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) CFG_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == CFG_REG_OFFSET)) CFG_REG <= dat_i[2-1:0]; + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) CTRL_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == CTRL_REG_OFFSET)) CTRL_REG <= dat_i[3-1:0]; + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + always @(posedge clk_i or posedge rst_i) + if (rst_i) PR_REG <= 'h2; + else if (wb_we & (adr_i[16-1:0] == PR_REG_OFFSET)) PR_REG <= dat_i[CDW-1:0]; + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) RX_FIFO_THRESHOLD_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET)) + RX_FIFO_THRESHOLD_REG <= dat_i[FAW-1:0]; + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) RX_FIFO_FLUSH_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET)) RX_FIFO_FLUSH_REG <= dat_i[1-1:0]; + else RX_FIFO_FLUSH_REG <= 1'h0 & RX_FIFO_FLUSH_REG; + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) TX_FIFO_THRESHOLD_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET)) + TX_FIFO_THRESHOLD_REG <= dat_i[FAW-1:0]; + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) TX_FIFO_FLUSH_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET)) TX_FIFO_FLUSH_REG <= dat_i[1-1:0]; + else TX_FIFO_FLUSH_REG <= 1'h0 & TX_FIFO_FLUSH_REG; + + localparam GCLK_REG_OFFSET = 16'hFF10; + always @(posedge clk_i or posedge rst_i) + if (rst_i) GCLK_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == GCLK_REG_OFFSET)) GCLK_REG <= dat_i[1-1:0]; + + reg [ 5:0] IM_REG; + reg [ 5:0] IC_REG; + reg [ 5:0] RIS_REG; + + wire [6-1:0] MIS_REG = RIS_REG & IM_REG; + always @(posedge clk_i or posedge rst_i) + if (rst_i) IM_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == IM_REG_OFFSET)) IM_REG <= dat_i[6-1:0]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) IC_REG <= 6'b0; + else if (wb_we & (adr_i[16-1:0] == IC_REG_OFFSET)) IC_REG <= dat_i[6-1:0]; + else IC_REG <= 6'd0; + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + always @(posedge clk_i or posedge rst_i) + if (rst_i) RIS_REG <= 0; + else begin + for (_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXE[_i_-0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXF[_i_-1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXE[_i_-2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXF[_i_-3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXB[_i_-4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXA[_i_-5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign dat_o = + (adr_i[16-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (adr_i[16-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (adr_i[16-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (adr_i[16-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (adr_i[16-1:0] == PR_REG_OFFSET) ? PR_REG : + (adr_i[16-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (adr_i[16-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (adr_i[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (adr_i[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (adr_i[16-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (adr_i[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (adr_i[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (adr_i[16-1:0] == IM_REG_OFFSET) ? IM_REG : + (adr_i[16-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (adr_i[16-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (adr_i[16-1:0] == IC_REG_OFFSET) ? IC_REG : 32'hDEADBEEF; - always @ (posedge clk_i or posedge rst_i) - if(rst_i) - ack_o <= 1'b0; - else if(wb_valid & ~ack_o) - ack_o <= 1'b1; - else - ack_o <= 1'b0; - assign RXDATA_WIRE = datao; - assign rd = ack_o & (wb_re & (adr_i[`WB_AW-1:0] == RXDATA_REG_OFFSET)); - assign datai = dat_i; - assign wr = ack_o & (wb_we & (adr_i[`WB_AW-1:0] == TXDATA_REG_OFFSET)); + always @(posedge clk_i or posedge rst_i) + if (rst_i) ack_o <= 1'b0; + else if (wb_valid & ~ack_o) ack_o <= 1'b1; + else ack_o <= 1'b0; + assign RXDATA_WIRE = datao; + assign rd = ack_o & (wb_re & (adr_i[16-1:0] == RXDATA_REG_OFFSET)); + assign datai = dat_i; + assign wr = ack_o & (wb_we & (adr_i[16-1:0] == TXDATA_REG_OFFSET)); endmodule diff --git a/hdl/rtl/bus_wrappers/dft/EF_SPI_AHBL_DFT.dev.v b/hdl/rtl/bus_wrappers/dft/EF_SPI_AHBL_DFT.dev.v new file mode 100644 index 0000000..c3df6c4 --- /dev/null +++ b/hdl/rtl/bus_wrappers/dft/EF_SPI_AHBL_DFT.dev.v @@ -0,0 +1,264 @@ +/* + Copyright 2024 Efabless Corp. + + Author: Efabless Corp. (ip_admin@efabless.com) + + 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. + +*/ + +/* THIS FILE IS GENERATED, DO NOT EDIT */ + +`timescale 1ns/1ps +`default_nettype none + +`define AHBL_AW 16 + +`include "ahbl_wrapper.vh" + +module EF_SPI_AHBL #( + parameter + CDW = 8, + FAW = 4 +) ( +`ifdef USE_POWER_PINS + inout VPWR, + inout VGND, +`endif + input wire sc_testmode, + `AHBL_SLAVE_PORTS, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk +); + + localparam RXDATA_REG_OFFSET = `AHBL_AW'h0000; + localparam TXDATA_REG_OFFSET = `AHBL_AW'h0004; + localparam CFG_REG_OFFSET = `AHBL_AW'h0008; + localparam CTRL_REG_OFFSET = `AHBL_AW'h000C; + localparam PR_REG_OFFSET = `AHBL_AW'h0010; + localparam STATUS_REG_OFFSET = `AHBL_AW'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = `AHBL_AW'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = `AHBL_AW'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = `AHBL_AW'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = `AHBL_AW'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = `AHBL_AW'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = `AHBL_AW'hFE18; + localparam IM_REG_OFFSET = `AHBL_AW'hFF00; + localparam MIS_REG_OFFSET = `AHBL_AW'hFF04; + localparam RIS_REG_OFFSET = `AHBL_AW'hFF08; + localparam IC_REG_OFFSET = `AHBL_AW'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = sc_testmode ? 1'b1 : GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell( + `ifdef USE_POWER_PINS + .vpwr(VPWR), + .vgnd(VGND), + `endif // USE_POWER_PINS + .clk(HCLK), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = HRESETn; + + + `AHBL_CTRL_SIGNALS + + wire [1-1:0] CPOL; + wire [1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [1-1:0] wr; + wire [1-1:0] rd; + wire [8-1:0] datai; + wire [8-1:0] datao; + wire [1-1:0] rx_en; + wire [1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [1-1:0] rx_empty; + wire [1-1:0] rx_full; + wire [1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [1-1:0] tx_empty; + wire [1-1:0] tx_full; + wire [1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [1-1:0] ss; + wire [1-1:0] enable; + wire [1-1:0] done; + wire [1-1:0] busy; + + // Register Definitions + wire [8-1:0] RXDATA_WIRE; + + wire [8-1:0] TXDATA_WIRE; + + reg [1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + `AHBL_REG(CFG_REG, 0, 2) + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + `AHBL_REG(CTRL_REG, 0, 3) + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + `AHBL_REG(PR_REG, 'h2, CDW) + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `AHBL_REG(RX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + `AHBL_REG_AC(RX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `AHBL_REG(TX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + `AHBL_REG_AC(TX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + localparam GCLK_REG_OFFSET = `AHBL_AW'hFF10; + `AHBL_REG(GCLK_REG, 0, 1) + + reg [5:0] IM_REG; + reg [5:0] IC_REG; + reg [5:0] RIS_REG; + + `AHBL_MIS_REG(6) + `AHBL_REG(IM_REG, 0, 6) + `AHBL_IC_REG(6) + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + `AHBL_BLOCK(RIS_REG, 0) else begin + for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign HRDATA = + (last_HADDR[`AHBL_AW-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (last_HADDR[`AHBL_AW-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (last_HADDR[`AHBL_AW-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (last_HADDR[`AHBL_AW-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (last_HADDR[`AHBL_AW-1:0] == PR_REG_OFFSET) ? PR_REG : + (last_HADDR[`AHBL_AW-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (last_HADDR[`AHBL_AW-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (last_HADDR[`AHBL_AW-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (last_HADDR[`AHBL_AW-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (last_HADDR[`AHBL_AW-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (last_HADDR[`AHBL_AW-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (last_HADDR[`AHBL_AW-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (last_HADDR[`AHBL_AW-1:0] == IM_REG_OFFSET) ? IM_REG : + (last_HADDR[`AHBL_AW-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (last_HADDR[`AHBL_AW-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (last_HADDR[`AHBL_AW-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : + 32'hDEADBEEF; + + assign HREADYOUT = 1'b1; + + assign RXDATA_WIRE = datao; + assign rd = (ahbl_re & (last_HADDR[`AHBL_AW-1:0] == RXDATA_REG_OFFSET)); + assign datai = HWDATA; + assign wr = (ahbl_we & (last_HADDR[`AHBL_AW-1:0] == TXDATA_REG_OFFSET)); +endmodule diff --git a/hdl/rtl/bus_wrappers/dft/EF_SPI_AHBL_DFT.v b/hdl/rtl/bus_wrappers/dft/EF_SPI_AHBL_DFT.v new file mode 100644 index 0000000..afa5555 --- /dev/null +++ b/hdl/rtl/bus_wrappers/dft/EF_SPI_AHBL_DFT.v @@ -0,0 +1,399 @@ +/* + Copyright 2024 Efabless Corp. + + Author: Efabless Corp. (ip_admin@efabless.com) + + 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. + +*/ + +/* THIS FILE IS GENERATED, DO NOT EDIT */ + +`timescale 1ns / 1ps `default_nettype none + + + + + + + + + + + + + + + + + + + + + +// PRINT_LICENSE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +module EF_SPI_AHBL #( + parameter CDW = 8, + FAW = 4 +) ( + + + + + input wire sc_testmode, + input wire HCLK, + input wire HRESETn, + input wire HWRITE, + input wire [ 31:0] HWDATA, + input wire [ 31:0] HADDR, + input wire [ 1:0] HTRANS, + input wire HSEL, + input wire HREADY, + output wire HREADYOUT, + output wire [ 31:0] HRDATA, + output wire IRQ, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk +); + + localparam RXDATA_REG_OFFSET = 16'h0000; + localparam TXDATA_REG_OFFSET = 16'h0004; + localparam CFG_REG_OFFSET = 16'h0008; + localparam CTRL_REG_OFFSET = 16'h000C; + localparam PR_REG_OFFSET = 16'h0010; + localparam STATUS_REG_OFFSET = 16'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = 16'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = 16'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = 16'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = 16'hFE18; + localparam IM_REG_OFFSET = 16'hFF00; + localparam MIS_REG_OFFSET = 16'hFF04; + localparam RIS_REG_OFFSET = 16'hFF08; + localparam IC_REG_OFFSET = 16'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = sc_testmode ? 1'b1 : GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell ( + + + + // USE_POWER_PINS + .clk(HCLK), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = HRESETn; + + + reg last_HSEL, last_HWRITE; + reg [31:0] last_HADDR; + reg [ 1:0] last_HTRANS; + always @(posedge HCLK or negedge HRESETn) begin + if (~HRESETn) begin + last_HSEL <= 1'b0; + last_HADDR <= 1'b0; + last_HWRITE <= 1'b0; + last_HTRANS <= 1'b0; + end else if (HREADY) begin + last_HSEL <= HSEL; + last_HADDR <= HADDR; + last_HWRITE <= HWRITE; + last_HTRANS <= HTRANS; + end + end + wire ahbl_valid = last_HSEL & last_HTRANS[1]; + wire ahbl_we = last_HWRITE & ahbl_valid; + wire ahbl_re = ~last_HWRITE & ahbl_valid; + + wire [1-1:0] CPOL; + wire [1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [1-1:0] wr; + wire [1-1:0] rd; + wire [8-1:0] datai; + wire [8-1:0] datao; + wire [1-1:0] rx_en; + wire [1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [1-1:0] rx_empty; + wire [1-1:0] rx_full; + wire [1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [1-1:0] tx_empty; + wire [1-1:0] tx_full; + wire [1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [1-1:0] ss; + wire [1-1:0] enable; + wire [1-1:0] done; + wire [1-1:0] busy; + + // Register Definitions + wire [8-1:0] RXDATA_WIRE; + + wire [8-1:0] TXDATA_WIRE; + + reg [1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) CFG_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == CFG_REG_OFFSET)) CFG_REG <= HWDATA[2-1:0]; + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) CTRL_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == CTRL_REG_OFFSET)) CTRL_REG <= HWDATA[3-1:0]; + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) PR_REG <= 'h2; + else if (ahbl_we & (last_HADDR[16-1:0] == PR_REG_OFFSET)) PR_REG <= HWDATA[CDW-1:0]; + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) RX_FIFO_THRESHOLD_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET)) + RX_FIFO_THRESHOLD_REG <= HWDATA[FAW-1:0]; + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) RX_FIFO_FLUSH_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET)) + RX_FIFO_FLUSH_REG <= HWDATA[1-1:0]; + else RX_FIFO_FLUSH_REG <= 1'h0 & RX_FIFO_FLUSH_REG; + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) TX_FIFO_THRESHOLD_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET)) + TX_FIFO_THRESHOLD_REG <= HWDATA[FAW-1:0]; + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) TX_FIFO_FLUSH_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET)) + TX_FIFO_FLUSH_REG <= HWDATA[1-1:0]; + else TX_FIFO_FLUSH_REG <= 1'h0 & TX_FIFO_FLUSH_REG; + + localparam GCLK_REG_OFFSET = 16'hFF10; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) GCLK_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == GCLK_REG_OFFSET)) GCLK_REG <= HWDATA[1-1:0]; + + reg [ 5:0] IM_REG; + reg [ 5:0] IC_REG; + reg [ 5:0] RIS_REG; + + wire [6-1:0] MIS_REG = RIS_REG & IM_REG; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) IM_REG <= 0; + else if (ahbl_we & (last_HADDR[16-1:0] == IM_REG_OFFSET)) IM_REG <= HWDATA[6-1:0]; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) IC_REG <= 6'b0; + else if (ahbl_we & (last_HADDR[16-1:0] == IC_REG_OFFSET)) IC_REG <= HWDATA[6-1:0]; + else IC_REG <= 6'd0; + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + always @(posedge HCLK or negedge HRESETn) + if (~HRESETn) RIS_REG <= 0; + else begin + for (_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXE[_i_-0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXF[_i_-1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXE[_i_-2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXF[_i_-3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXB[_i_-4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXA[_i_-5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign HRDATA = + (last_HADDR[16-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (last_HADDR[16-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (last_HADDR[16-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (last_HADDR[16-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (last_HADDR[16-1:0] == PR_REG_OFFSET) ? PR_REG : + (last_HADDR[16-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (last_HADDR[16-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (last_HADDR[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (last_HADDR[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (last_HADDR[16-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (last_HADDR[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (last_HADDR[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (last_HADDR[16-1:0] == IM_REG_OFFSET) ? IM_REG : + (last_HADDR[16-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (last_HADDR[16-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (last_HADDR[16-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : + 32'hDEADBEEF; + + assign HREADYOUT = 1'b1; + + assign RXDATA_WIRE = datao; + assign rd = (ahbl_re & (last_HADDR[16-1:0] == RXDATA_REG_OFFSET)); + assign datai = HWDATA; + assign wr = (ahbl_we & (last_HADDR[16-1:0] == TXDATA_REG_OFFSET)); +endmodule diff --git a/hdl/rtl/bus_wrappers/dft/EF_SPI_APB_DFT.dev.v b/hdl/rtl/bus_wrappers/dft/EF_SPI_APB_DFT.dev.v new file mode 100644 index 0000000..2283dc9 --- /dev/null +++ b/hdl/rtl/bus_wrappers/dft/EF_SPI_APB_DFT.dev.v @@ -0,0 +1,264 @@ +/* + Copyright 2024 Efabless Corp. + + Author: Efabless Corp. (ip_admin@efabless.com) + + 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. + +*/ + +/* THIS FILE IS GENERATED, DO NOT EDIT */ + +`timescale 1ns/1ps +`default_nettype none + +`define APB_AW 16 + +`include "apb_wrapper.vh" + +module EF_SPI_APB #( + parameter + CDW = 8, + FAW = 4 +) ( +`ifdef USE_POWER_PINS + inout VPWR, + inout VGND, +`endif + input wire sc_testmode, + `APB_SLAVE_PORTS, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk +); + + localparam RXDATA_REG_OFFSET = `APB_AW'h0000; + localparam TXDATA_REG_OFFSET = `APB_AW'h0004; + localparam CFG_REG_OFFSET = `APB_AW'h0008; + localparam CTRL_REG_OFFSET = `APB_AW'h000C; + localparam PR_REG_OFFSET = `APB_AW'h0010; + localparam STATUS_REG_OFFSET = `APB_AW'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = `APB_AW'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = `APB_AW'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = `APB_AW'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = `APB_AW'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = `APB_AW'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = `APB_AW'hFE18; + localparam IM_REG_OFFSET = `APB_AW'hFF00; + localparam MIS_REG_OFFSET = `APB_AW'hFF04; + localparam RIS_REG_OFFSET = `APB_AW'hFF08; + localparam IC_REG_OFFSET = `APB_AW'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = sc_testmode ? 1'b1 : GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell( + `ifdef USE_POWER_PINS + .vpwr(VPWR), + .vgnd(VGND), + `endif // USE_POWER_PINS + .clk(PCLK), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = PRESETn; + + + `APB_CTRL_SIGNALS + + wire [1-1:0] CPOL; + wire [1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [1-1:0] wr; + wire [1-1:0] rd; + wire [8-1:0] datai; + wire [8-1:0] datao; + wire [1-1:0] rx_en; + wire [1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [1-1:0] rx_empty; + wire [1-1:0] rx_full; + wire [1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [1-1:0] tx_empty; + wire [1-1:0] tx_full; + wire [1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [1-1:0] ss; + wire [1-1:0] enable; + wire [1-1:0] done; + wire [1-1:0] busy; + + // Register Definitions + wire [8-1:0] RXDATA_WIRE; + + wire [8-1:0] TXDATA_WIRE; + + reg [1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + `APB_REG(CFG_REG, 0, 2) + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + `APB_REG(CTRL_REG, 0, 3) + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + `APB_REG(PR_REG, 'h2, CDW) + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `APB_REG(RX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + `APB_REG_AC(RX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `APB_REG(TX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + `APB_REG_AC(TX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + localparam GCLK_REG_OFFSET = `APB_AW'hFF10; + `APB_REG(GCLK_REG, 0, 1) + + reg [5:0] IM_REG; + reg [5:0] IC_REG; + reg [5:0] RIS_REG; + + `APB_MIS_REG(6) + `APB_REG(IM_REG, 0, 6) + `APB_IC_REG(6) + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + `APB_BLOCK(RIS_REG, 0) else begin + for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign PRDATA = + (PADDR[`APB_AW-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (PADDR[`APB_AW-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (PADDR[`APB_AW-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (PADDR[`APB_AW-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (PADDR[`APB_AW-1:0] == PR_REG_OFFSET) ? PR_REG : + (PADDR[`APB_AW-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (PADDR[`APB_AW-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (PADDR[`APB_AW-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (PADDR[`APB_AW-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (PADDR[`APB_AW-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (PADDR[`APB_AW-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (PADDR[`APB_AW-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (PADDR[`APB_AW-1:0] == IM_REG_OFFSET) ? IM_REG : + (PADDR[`APB_AW-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (PADDR[`APB_AW-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (PADDR[`APB_AW-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : + 32'hDEADBEEF; + + assign PREADY = 1'b1; + + assign RXDATA_WIRE = datao; + assign rd = (apb_re & (PADDR[`APB_AW-1:0] == RXDATA_REG_OFFSET)); + assign datai = PWDATA; + assign wr = (apb_we & (PADDR[`APB_AW-1:0] == TXDATA_REG_OFFSET)); +endmodule diff --git a/hdl/rtl/bus_wrappers/dft/EF_SPI_APB_DFT.v b/hdl/rtl/bus_wrappers/dft/EF_SPI_APB_DFT.v new file mode 100644 index 0000000..f7815d5 --- /dev/null +++ b/hdl/rtl/bus_wrappers/dft/EF_SPI_APB_DFT.v @@ -0,0 +1,381 @@ +/* + Copyright 2024 Efabless Corp. + + Author: Efabless Corp. (ip_admin@efabless.com) + + 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. + +*/ + +/* THIS FILE IS GENERATED, DO NOT EDIT */ + +`timescale 1ns / 1ps `default_nettype none + + + + + + + + + + + + + + + + + + + + + +// PRINT_LICENSE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +module EF_SPI_APB #( + parameter CDW = 8, + FAW = 4 +) ( + + + + + input wire sc_testmode, + input wire PCLK, + input wire PRESETn, + input wire PWRITE, + input wire [ 31:0] PWDATA, + input wire [ 31:0] PADDR, + input wire PENABLE, + input wire PSEL, + output wire PREADY, + output wire [ 31:0] PRDATA, + output wire IRQ, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk +); + + localparam RXDATA_REG_OFFSET = 16'h0000; + localparam TXDATA_REG_OFFSET = 16'h0004; + localparam CFG_REG_OFFSET = 16'h0008; + localparam CTRL_REG_OFFSET = 16'h000C; + localparam PR_REG_OFFSET = 16'h0010; + localparam STATUS_REG_OFFSET = 16'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = 16'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = 16'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = 16'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = 16'hFE18; + localparam IM_REG_OFFSET = 16'hFF00; + localparam MIS_REG_OFFSET = 16'hFF04; + localparam RIS_REG_OFFSET = 16'hFF08; + localparam IC_REG_OFFSET = 16'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = sc_testmode ? 1'b1 : GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell ( + + + + // USE_POWER_PINS + .clk(PCLK), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = PRESETn; + + + wire apb_valid = PSEL & PENABLE; + wire apb_we = PWRITE & apb_valid; + wire apb_re = ~PWRITE & apb_valid; + + wire [ 1-1:0] CPOL; + wire [ 1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [ 1-1:0] wr; + wire [ 1-1:0] rd; + wire [ 8-1:0] datai; + wire [ 8-1:0] datao; + wire [ 1-1:0] rx_en; + wire [ 1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [ 1-1:0] rx_empty; + wire [ 1-1:0] rx_full; + wire [ 1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [ 1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [ 1-1:0] tx_empty; + wire [ 1-1:0] tx_full; + wire [ 1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [ 1-1:0] ss; + wire [ 1-1:0] enable; + wire [ 1-1:0] done; + wire [ 1-1:0] busy; + + // Register Definitions + wire [ 8-1:0] RXDATA_WIRE; + + wire [ 8-1:0] TXDATA_WIRE; + + reg [ 1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) CFG_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == CFG_REG_OFFSET)) CFG_REG <= PWDATA[2-1:0]; + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) CTRL_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == CTRL_REG_OFFSET)) CTRL_REG <= PWDATA[3-1:0]; + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) PR_REG <= 'h2; + else if (apb_we & (PADDR[16-1:0] == PR_REG_OFFSET)) PR_REG <= PWDATA[CDW-1:0]; + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) RX_FIFO_THRESHOLD_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET)) + RX_FIFO_THRESHOLD_REG <= PWDATA[FAW-1:0]; + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) RX_FIFO_FLUSH_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET)) + RX_FIFO_FLUSH_REG <= PWDATA[1-1:0]; + else RX_FIFO_FLUSH_REG <= 1'h0 & RX_FIFO_FLUSH_REG; + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) TX_FIFO_THRESHOLD_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET)) + TX_FIFO_THRESHOLD_REG <= PWDATA[FAW-1:0]; + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) TX_FIFO_FLUSH_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET)) + TX_FIFO_FLUSH_REG <= PWDATA[1-1:0]; + else TX_FIFO_FLUSH_REG <= 1'h0 & TX_FIFO_FLUSH_REG; + + localparam GCLK_REG_OFFSET = 16'hFF10; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) GCLK_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == GCLK_REG_OFFSET)) GCLK_REG <= PWDATA[1-1:0]; + + reg [ 5:0] IM_REG; + reg [ 5:0] IC_REG; + reg [ 5:0] RIS_REG; + + wire [6-1:0] MIS_REG = RIS_REG & IM_REG; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) IM_REG <= 0; + else if (apb_we & (PADDR[16-1:0] == IM_REG_OFFSET)) IM_REG <= PWDATA[6-1:0]; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) IC_REG <= 6'b0; + else if (apb_we & (PADDR[16-1:0] == IC_REG_OFFSET)) IC_REG <= PWDATA[6-1:0]; + else IC_REG <= 6'd0; + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + always @(posedge PCLK or negedge PRESETn) + if (~PRESETn) RIS_REG <= 0; + else begin + for (_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXE[_i_-0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXF[_i_-1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXE[_i_-2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXF[_i_-3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXB[_i_-4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXA[_i_-5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign PRDATA = + (PADDR[16-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (PADDR[16-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (PADDR[16-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (PADDR[16-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (PADDR[16-1:0] == PR_REG_OFFSET) ? PR_REG : + (PADDR[16-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (PADDR[16-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (PADDR[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (PADDR[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (PADDR[16-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (PADDR[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (PADDR[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (PADDR[16-1:0] == IM_REG_OFFSET) ? IM_REG : + (PADDR[16-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (PADDR[16-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (PADDR[16-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : + 32'hDEADBEEF; + + assign PREADY = 1'b1; + + assign RXDATA_WIRE = datao; + assign rd = (apb_re & (PADDR[16-1:0] == RXDATA_REG_OFFSET)); + assign datai = PWDATA; + assign wr = (apb_we & (PADDR[16-1:0] == TXDATA_REG_OFFSET)); +endmodule diff --git a/hdl/rtl/bus_wrappers/dft/EF_SPI_WB_DFT.dev.v b/hdl/rtl/bus_wrappers/dft/EF_SPI_WB_DFT.dev.v new file mode 100644 index 0000000..3cdbc01 --- /dev/null +++ b/hdl/rtl/bus_wrappers/dft/EF_SPI_WB_DFT.dev.v @@ -0,0 +1,269 @@ +/* + Copyright 2024 Efabless Corp. + + Author: Efabless Corp. (ip_admin@efabless.com) + + 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. + +*/ + +/* THIS FILE IS GENERATED, DO NOT EDIT */ + +`timescale 1ns/1ps +`default_nettype none + +`define WB_AW 16 + +`include "wb_wrapper.vh" + +module EF_SPI_WB #( + parameter + CDW = 8, + FAW = 4 +) ( +`ifdef USE_POWER_PINS + inout VPWR, + inout VGND, +`endif + input wire sc_testmode, + `WB_SLAVE_PORTS, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk +); + + localparam RXDATA_REG_OFFSET = `WB_AW'h0000; + localparam TXDATA_REG_OFFSET = `WB_AW'h0004; + localparam CFG_REG_OFFSET = `WB_AW'h0008; + localparam CTRL_REG_OFFSET = `WB_AW'h000C; + localparam PR_REG_OFFSET = `WB_AW'h0010; + localparam STATUS_REG_OFFSET = `WB_AW'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = `WB_AW'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = `WB_AW'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = `WB_AW'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = `WB_AW'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = `WB_AW'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = `WB_AW'hFE18; + localparam IM_REG_OFFSET = `WB_AW'hFF00; + localparam MIS_REG_OFFSET = `WB_AW'hFF04; + localparam RIS_REG_OFFSET = `WB_AW'hFF08; + localparam IC_REG_OFFSET = `WB_AW'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = sc_testmode ? 1'b1 : GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell( + `ifdef USE_POWER_PINS + .vpwr(VPWR), + .vgnd(VGND), + `endif // USE_POWER_PINS + .clk(clk_i), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = (~rst_i); + + + `WB_CTRL_SIGNALS + + wire [1-1:0] CPOL; + wire [1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [1-1:0] wr; + wire [1-1:0] rd; + wire [8-1:0] datai; + wire [8-1:0] datao; + wire [1-1:0] rx_en; + wire [1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [1-1:0] rx_empty; + wire [1-1:0] rx_full; + wire [1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [1-1:0] tx_empty; + wire [1-1:0] tx_full; + wire [1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [1-1:0] ss; + wire [1-1:0] enable; + wire [1-1:0] done; + wire [1-1:0] busy; + + // Register Definitions + wire [8-1:0] RXDATA_WIRE; + + wire [8-1:0] TXDATA_WIRE; + + reg [1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + `WB_REG(CFG_REG, 0, 2) + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + `WB_REG(CTRL_REG, 0, 3) + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + `WB_REG(PR_REG, 'h2, CDW) + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `WB_REG(RX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + `WB_REG_AC(RX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW - 1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW - 1) : 0]; + `WB_REG(TX_FIFO_THRESHOLD_REG, 0, FAW) + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + `WB_REG_AC(TX_FIFO_FLUSH_REG, 0, 1, 1'h0) + + localparam GCLK_REG_OFFSET = `WB_AW'hFF10; + `WB_REG(GCLK_REG, 0, 1) + + reg [5:0] IM_REG; + reg [5:0] IC_REG; + reg [5:0] RIS_REG; + + `WB_MIS_REG(6) + `WB_REG(IM_REG, 0, 6) + `WB_IC_REG(6) + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + `WB_BLOCK(RIS_REG, 0) else begin + for(_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXE[_i_ - 0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXF[_i_ - 1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXE[_i_ - 2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXF[_i_ - 3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(TXB[_i_ - 4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for(_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if(IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; else if(RXA[_i_ - 5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign dat_o = + (adr_i[`WB_AW-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (adr_i[`WB_AW-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (adr_i[`WB_AW-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (adr_i[`WB_AW-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (adr_i[`WB_AW-1:0] == PR_REG_OFFSET) ? PR_REG : + (adr_i[`WB_AW-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (adr_i[`WB_AW-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (adr_i[`WB_AW-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (adr_i[`WB_AW-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (adr_i[`WB_AW-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (adr_i[`WB_AW-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (adr_i[`WB_AW-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (adr_i[`WB_AW-1:0] == IM_REG_OFFSET) ? IM_REG : + (adr_i[`WB_AW-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (adr_i[`WB_AW-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (adr_i[`WB_AW-1:0] == IC_REG_OFFSET) ? IC_REG : + 32'hDEADBEEF; + + always @ (posedge clk_i or posedge rst_i) + if(rst_i) + ack_o <= 1'b0; + else if(wb_valid & ~ack_o) + ack_o <= 1'b1; + else + ack_o <= 1'b0; + assign RXDATA_WIRE = datao; + assign rd = ack_o & (wb_re & (adr_i[`WB_AW-1:0] == RXDATA_REG_OFFSET)); + assign datai = dat_i; + assign wr = ack_o & (wb_we & (adr_i[`WB_AW-1:0] == TXDATA_REG_OFFSET)); +endmodule diff --git a/hdl/rtl/bus_wrappers/dft/EF_SPI_WB_DFT.v b/hdl/rtl/bus_wrappers/dft/EF_SPI_WB_DFT.v new file mode 100644 index 0000000..88db435 --- /dev/null +++ b/hdl/rtl/bus_wrappers/dft/EF_SPI_WB_DFT.v @@ -0,0 +1,361 @@ +/* + Copyright 2024 Efabless Corp. + + Author: Efabless Corp. (ip_admin@efabless.com) + + 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. + +*/ + +/* THIS FILE IS GENERATED, DO NOT EDIT */ + +`timescale 1ns / 1ps `default_nettype none + + + + + + + + + + + + + + + + + + + + + +// PRINT_LICENSE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +module EF_SPI_WB #( + parameter CDW = 8, + FAW = 4 +) ( + + + + + input wire sc_testmode, + input wire clk_i, + input wire rst_i, + input wire [ 31:0] adr_i, + input wire [ 31:0] dat_i, + output wire [ 31:0] dat_o, + input wire [ 3:0] sel_i, + input wire cyc_i, + input wire stb_i, + output reg ack_o, + input wire we_i, + output wire IRQ, + input wire [1-1:0] miso, + output wire [1-1:0] mosi, + output wire [1-1:0] csb, + output wire [1-1:0] sclk +); + + localparam RXDATA_REG_OFFSET = 16'h0000; + localparam TXDATA_REG_OFFSET = 16'h0004; + localparam CFG_REG_OFFSET = 16'h0008; + localparam CTRL_REG_OFFSET = 16'h000C; + localparam PR_REG_OFFSET = 16'h0010; + localparam STATUS_REG_OFFSET = 16'h0014; + localparam RX_FIFO_LEVEL_REG_OFFSET = 16'hFE00; + localparam RX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE04; + localparam RX_FIFO_FLUSH_REG_OFFSET = 16'hFE08; + localparam TX_FIFO_LEVEL_REG_OFFSET = 16'hFE10; + localparam TX_FIFO_THRESHOLD_REG_OFFSET = 16'hFE14; + localparam TX_FIFO_FLUSH_REG_OFFSET = 16'hFE18; + localparam IM_REG_OFFSET = 16'hFF00; + localparam MIS_REG_OFFSET = 16'hFF04; + localparam RIS_REG_OFFSET = 16'hFF08; + localparam IC_REG_OFFSET = 16'hFF0C; + + reg [0:0] GCLK_REG; + wire clk_g; + + wire clk_gated_en = sc_testmode ? 1'b1 : GCLK_REG[0]; + ef_util_gating_cell clk_gate_cell ( + + + + // USE_POWER_PINS + .clk(clk_i), + .clk_en(clk_gated_en), + .clk_o(clk_g) + ); + + wire clk = clk_g; + wire rst_n = (~rst_i); + + + wire wb_valid = cyc_i & stb_i; + wire wb_we = we_i & wb_valid; + wire wb_re = ~we_i & wb_valid; + wire [ 3:0] wb_byte_sel = sel_i & {4{wb_we}}; + + wire [ 1-1:0] CPOL; + wire [ 1-1:0] CPHA; + wire [CDW-1:0] clk_divider; + wire [ 1-1:0] wr; + wire [ 1-1:0] rd; + wire [ 8-1:0] datai; + wire [ 8-1:0] datao; + wire [ 1-1:0] rx_en; + wire [ 1-1:0] rx_flush; + wire [FAW-1:0] rx_threshold; + wire [ 1-1:0] rx_empty; + wire [ 1-1:0] rx_full; + wire [ 1-1:0] rx_level_above; + wire [FAW-1:0] rx_level; + wire [ 1-1:0] tx_flush; + wire [FAW-1:0] tx_threshold; + wire [ 1-1:0] tx_empty; + wire [ 1-1:0] tx_full; + wire [ 1-1:0] tx_level_below; + wire [FAW-1:0] tx_level; + wire [ 1-1:0] ss; + wire [ 1-1:0] enable; + wire [ 1-1:0] done; + wire [ 1-1:0] busy; + + // Register Definitions + wire [ 8-1:0] RXDATA_WIRE; + + wire [ 8-1:0] TXDATA_WIRE; + + reg [ 1:0] CFG_REG; + assign CPOL = CFG_REG[0 : 0]; + assign CPHA = CFG_REG[1 : 1]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) CFG_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == CFG_REG_OFFSET)) CFG_REG <= dat_i[2-1:0]; + + reg [2:0] CTRL_REG; + assign ss = CTRL_REG[0 : 0]; + assign enable = CTRL_REG[1 : 1]; + assign rx_en = CTRL_REG[2 : 2]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) CTRL_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == CTRL_REG_OFFSET)) CTRL_REG <= dat_i[3-1:0]; + + reg [CDW-1:0] PR_REG; + assign clk_divider = PR_REG; + always @(posedge clk_i or posedge rst_i) + if (rst_i) PR_REG <= 'h2; + else if (wb_we & (adr_i[16-1:0] == PR_REG_OFFSET)) PR_REG <= dat_i[CDW-1:0]; + + wire [8-1:0] STATUS_WIRE; + assign STATUS_WIRE[0 : 0] = tx_empty; + assign STATUS_WIRE[1 : 1] = tx_full; + assign STATUS_WIRE[2 : 2] = rx_empty; + assign STATUS_WIRE[3 : 3] = rx_full; + assign STATUS_WIRE[4 : 4] = tx_level_below; + assign STATUS_WIRE[5 : 5] = rx_level_above; + assign STATUS_WIRE[6 : 6] = busy; + assign STATUS_WIRE[7 : 7] = done; + + wire [FAW-1:0] RX_FIFO_LEVEL_WIRE; + assign RX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = rx_level; + + reg [FAW-1:0] RX_FIFO_THRESHOLD_REG; + assign rx_threshold = RX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) RX_FIFO_THRESHOLD_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET)) + RX_FIFO_THRESHOLD_REG <= dat_i[FAW-1:0]; + + reg [0:0] RX_FIFO_FLUSH_REG; + assign rx_flush = RX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) RX_FIFO_FLUSH_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET)) RX_FIFO_FLUSH_REG <= dat_i[1-1:0]; + else RX_FIFO_FLUSH_REG <= 1'h0 & RX_FIFO_FLUSH_REG; + + wire [FAW-1:0] TX_FIFO_LEVEL_WIRE; + assign TX_FIFO_LEVEL_WIRE[(FAW-1) : 0] = tx_level; + + reg [FAW-1:0] TX_FIFO_THRESHOLD_REG; + assign tx_threshold = TX_FIFO_THRESHOLD_REG[(FAW-1) : 0]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) TX_FIFO_THRESHOLD_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET)) + TX_FIFO_THRESHOLD_REG <= dat_i[FAW-1:0]; + + reg [0:0] TX_FIFO_FLUSH_REG; + assign tx_flush = TX_FIFO_FLUSH_REG[0 : 0]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) TX_FIFO_FLUSH_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET)) TX_FIFO_FLUSH_REG <= dat_i[1-1:0]; + else TX_FIFO_FLUSH_REG <= 1'h0 & TX_FIFO_FLUSH_REG; + + localparam GCLK_REG_OFFSET = 16'hFF10; + always @(posedge clk_i or posedge rst_i) + if (rst_i) GCLK_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == GCLK_REG_OFFSET)) GCLK_REG <= dat_i[1-1:0]; + + reg [ 5:0] IM_REG; + reg [ 5:0] IC_REG; + reg [ 5:0] RIS_REG; + + wire [6-1:0] MIS_REG = RIS_REG & IM_REG; + always @(posedge clk_i or posedge rst_i) + if (rst_i) IM_REG <= 0; + else if (wb_we & (adr_i[16-1:0] == IM_REG_OFFSET)) IM_REG <= dat_i[6-1:0]; + always @(posedge clk_i or posedge rst_i) + if (rst_i) IC_REG <= 6'b0; + else if (wb_we & (adr_i[16-1:0] == IC_REG_OFFSET)) IC_REG <= dat_i[6-1:0]; + else IC_REG <= 6'd0; + + wire [0:0] TXE = tx_empty; + wire [0:0] TXF = tx_full; + wire [0:0] RXE = rx_empty; + wire [0:0] RXF = rx_full; + wire [0:0] TXB = tx_level_below; + wire [0:0] RXA = rx_level_above; + + + integer _i_; + always @(posedge clk_i or posedge rst_i) + if (rst_i) RIS_REG <= 0; + else begin + for (_i_ = 0; _i_ < 1; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXE[_i_-0] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 1; _i_ < 2; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXF[_i_-1] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 2; _i_ < 3; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXE[_i_-2] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 3; _i_ < 4; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXF[_i_-3] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 4; _i_ < 5; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (TXB[_i_-4] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + for (_i_ = 5; _i_ < 6; _i_ = _i_ + 1) begin + if (IC_REG[_i_]) RIS_REG[_i_] <= 1'b0; + else if (RXA[_i_-5] == 1'b1) RIS_REG[_i_] <= 1'b1; + end + end + + assign IRQ = |MIS_REG; + + EF_SPI #( + .CDW(CDW), + .FAW(FAW) + ) instance_to_wrap ( + .clk(clk), + .rst_n(rst_n), + .CPOL(CPOL), + .CPHA(CPHA), + .clk_divider(clk_divider), + .wr(wr), + .rd(rd), + .datai(datai), + .datao(datao), + .rx_en(rx_en), + .rx_flush(rx_flush), + .rx_threshold(rx_threshold), + .rx_empty(rx_empty), + .rx_full(rx_full), + .rx_level_above(rx_level_above), + .rx_level(rx_level), + .tx_flush(tx_flush), + .tx_threshold(tx_threshold), + .tx_empty(tx_empty), + .tx_full(tx_full), + .tx_level_below(tx_level_below), + .tx_level(tx_level), + .ss(ss), + .enable(enable), + .done(done), + .busy(busy), + .miso(miso), + .mosi(mosi), + .csb(csb), + .sclk(sclk) + ); + + assign dat_o = + (adr_i[16-1:0] == RXDATA_REG_OFFSET) ? RXDATA_WIRE : + (adr_i[16-1:0] == TXDATA_REG_OFFSET) ? TXDATA_WIRE : + (adr_i[16-1:0] == CFG_REG_OFFSET) ? CFG_REG : + (adr_i[16-1:0] == CTRL_REG_OFFSET) ? CTRL_REG : + (adr_i[16-1:0] == PR_REG_OFFSET) ? PR_REG : + (adr_i[16-1:0] == STATUS_REG_OFFSET) ? STATUS_WIRE : + (adr_i[16-1:0] == RX_FIFO_LEVEL_REG_OFFSET) ? RX_FIFO_LEVEL_WIRE : + (adr_i[16-1:0] == RX_FIFO_THRESHOLD_REG_OFFSET) ? RX_FIFO_THRESHOLD_REG : + (adr_i[16-1:0] == RX_FIFO_FLUSH_REG_OFFSET) ? RX_FIFO_FLUSH_REG : + (adr_i[16-1:0] == TX_FIFO_LEVEL_REG_OFFSET) ? TX_FIFO_LEVEL_WIRE : + (adr_i[16-1:0] == TX_FIFO_THRESHOLD_REG_OFFSET) ? TX_FIFO_THRESHOLD_REG : + (adr_i[16-1:0] == TX_FIFO_FLUSH_REG_OFFSET) ? TX_FIFO_FLUSH_REG : + (adr_i[16-1:0] == IM_REG_OFFSET) ? IM_REG : + (adr_i[16-1:0] == MIS_REG_OFFSET) ? MIS_REG : + (adr_i[16-1:0] == RIS_REG_OFFSET) ? RIS_REG : + (adr_i[16-1:0] == IC_REG_OFFSET) ? IC_REG : + 32'hDEADBEEF; + + always @(posedge clk_i or posedge rst_i) + if (rst_i) ack_o <= 1'b0; + else if (wb_valid & ~ack_o) ack_o <= 1'b1; + else ack_o <= 1'b0; + assign RXDATA_WIRE = datao; + assign rd = ack_o & (wb_re & (adr_i[16-1:0] == RXDATA_REG_OFFSET)); + assign datai = dat_i; + assign wr = ack_o & (wb_we & (adr_i[16-1:0] == TXDATA_REG_OFFSET)); +endmodule diff --git a/ip/dependencies.json b/ip/dependencies.json index bc86f84..2474569 100644 --- a/ip/dependencies.json +++ b/ip/dependencies.json @@ -1,7 +1,7 @@ { "IP": [ { - "IP_Utilities": "v1.0.0" + "EF_IP_UTIL": "v1.0.0" } ] } \ No newline at end of file diff --git a/ipm_package.bash b/ipm_package.bash new file mode 100644 index 0000000..57333e2 --- /dev/null +++ b/ipm_package.bash @@ -0,0 +1,55 @@ +#!/bin/bash +# More safety, by turning some bugs into errors. +set -o errexit -o pipefail -o nounset + +# now enjoy the options in order and nicely split until we see -- +# option --output/-o requires 1 argument +LONGOPTS=version: +OPTIONS= + +# -temporarily store output to be able to check for errors +# -activate quoting/enhanced mode (e.g. by writing out "--options") +# -pass arguments only via -- "$@" to separate them correctly +# -if getopt fails, it complains itself to stdout +PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@") || exit 2 +# read getopt's output this way to handle the quoting right: +eval set -- "$PARSED" +unset PARSED + + +while true; do + case "$1" in + --version) + version="$2" + shift 2 + ;; + --) + shift + break + ;; + *) + echo "Programming error" + exit 3 + ;; + esac +done + +echo "+ version=$version" + +# zip needed files +tar czf v$version.tar.gz hdl/ef_util_lib.v fw +# get checksum +shasum -a 256 v$version.tar.gz > v$version.tar.gz.sha256 + +# create tag +git tag -a EF_IP_UTIL-v$version -m "Release version $version" +git push origin EF_IP_UTIL-v$version + +# create release +set -x +if gh release view EF_IP_UTIL-v$version > /dev/null 2>&1; then + echo "Release EF_IP_UTIL-v$version already exists. Skipping..." +else + echo "Creating release EF_IP_UTIL-v$version..." + gh release create EF_IP_UTIL-v$version v$version.tar.gz -t "EF_IP_UTIL-v$version" --notes "sha256: $(cat v$version.tar.gz.sha256)" +fi \ No newline at end of file diff --git a/verify/README.md b/verify/README.md new file mode 100644 index 0000000..79a7572 --- /dev/null +++ b/verify/README.md @@ -0,0 +1,31 @@ +## Run cocotb UVM Testbench: +In IP directory run: + ```shell + cd verify/uvm-python/ + ``` + ##### To run testbench for design with APB + To run all tests: + ```shell + make run_all_tests BUS_TYPE=APB + ``` + To run a certain test: + ```shell + make run_ BUS_TYPE=APB + ``` + To run all tests with a tag: + ```shell + make run_all_tests TAG= BUS_TYPE=APB + ``` + ##### To run testbench for design with APB + To run all tests: + ```shell + make run_all_tests BUS_TYPE=AHB + ``` + To run a certain test: + ```shell + make run_ BUS_TYPE=AHB + ``` + To run all tests with a tag: + ```shell + make run_all_tests TAG= BUS_TYPE=AHB +``` diff --git a/verify/uvm-python/Makefile b/verify/uvm-python/Makefile index 88d7085..6c881b7 100644 --- a/verify/uvm-python/Makefile +++ b/verify/uvm-python/Makefile @@ -1,10 +1,10 @@ PLUSARGS += "+UVM_VERBOSITY=UVM_MEDUIM" TOPLEVEL := top MODULE ?= top_module -AHB_FILES ?= $(PWD)/../../hdl/rtl/bus_wrappers/EF_SPI_AHBL.pp.v -APB_FILES ?= $(PWD)/../../hdl/rtl/bus_wrappers/EF_SPI_APB.pp.v -WB_FILES ?=$(PWD)/../../hdl/rtl/bus_wrappers/EF_SPI_WB.pp.v -HDL_FILES ?= $(PWD)/../../ip/IP_Utilities/rtl/aucohl_lib.v $(PWD)/../../ip/IP_Utilities/rtl/aucohl_rtl.vh $(PWD)/../../hdl/rtl/spi_master.v $(PWD)/../../hdl/rtl/EF_SPI.v +AHB_FILES ?= $(PWD)/../../hdl/rtl/bus_wrappers/EF_SPI_AHBL.v +APB_FILES ?= $(PWD)/../../hdl/rtl/bus_wrappers/EF_SPI_APB.v +WB_FILES ?=$(PWD)/../../hdl/rtl/bus_wrappers/EF_SPI_WB.v +HDL_FILES ?= $(PWD)/../../ip/EF_IP_UTIL/rtl/aucohl_lib.v $(PWD)/../../ip/EF_IP_UTIL/rtl/aucohl_rtl.vh $(PWD)/../../hdl/rtl/spi_master.v $(PWD)/../../hdl/rtl/EF_SPI.v VERILOG_SOURCES ?= $(PWD)/top.v $(AHB_FILES) $(APB_FILES) $(WB_FILES) $(HDL_FILES) RTL_MACROS += ""