usb bug fix
diff --git a/verilog/dv/user_usb/Makefile b/verilog/dv/user_usb/Makefile
new file mode 100644
index 0000000..3e082d3
--- /dev/null
+++ b/verilog/dv/user_usb/Makefile
@@ -0,0 +1,101 @@
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+#
+# 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+## Caravel Pointers
+CARAVEL_ROOT ?= ../../../caravel
+CARAVEL_PATH ?= $(CARAVEL_ROOT)
+CARAVEL_FIRMWARE_PATH = $(CARAVEL_PATH)/verilog/dv/caravel
+CARAVEL_VERILOG_PATH = $(CARAVEL_PATH)/verilog
+CARAVEL_RTL_PATH = $(CARAVEL_VERILOG_PATH)/rtl
+CARAVEL_BEHAVIOURAL_MODELS = $(CARAVEL_VERILOG_PATH)/dv/caravel
+
+
+## User Project Pointers
+UPRJ_VERILOG_PATH ?= ../../../verilog
+UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
+UPRJ_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_BEHAVIOURAL_BFM = ../bfm
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr2c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+
+## YIFIVE FIRMWARE
+YIFIVE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/dv/firmware
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## RISCV GCC
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/opt/pdk/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+RISC_CORE?=0
+
+.SUFFIXES:
+
+PATTERN = user_usb
+
+all: ${PATTERN:=.vcd}
+
+
+vvp: ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+ifeq ($(SIM),RTL)
+ ifeq ($(DUMP),OFF)
+ iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+ -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_AGENTS) -I $(UPRJ_BEHAVIOURAL_BFM) \
+ -I $(UPRJ_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+ -I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+ $< -o $@
+ else
+ iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+ -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_AGENTS) -I $(UPRJ_BEHAVIOURAL_BFM) \
+ -I $(UPRJ_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+ -I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+ $< -o $@
+ endif
+else
+ iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+ -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_GL_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_AGENTS) \
+ $< -o $@
+endif
+
+%.vcd: %.vvp
+ vvp $<
+
+%.hex:
+ echo @"This is user boot test, noting to compile the mangment core code"
+
+
+# ---- Clean ----
+
+clean:
+ rm -f *.vvp *.vcd *.log *.fst
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_usb/tests/usb_test1.v b/verilog/dv/user_usb/tests/usb_test1.v
new file mode 100755
index 0000000..1522d08
--- /dev/null
+++ b/verilog/dv/user_usb/tests/usb_test1.v
@@ -0,0 +1,56 @@
+`define usbbfm u_usb_agent
+task usb_test1;
+
+reg [6:0] address;
+reg [3:0] endpt;
+reg [3:0] Status;
+reg [31:0] ByteCount;
+
+integer i,j;
+reg [7:0] startbyte;
+reg [15:0] mask;
+integer MaxPktSize;
+reg [3:0] PackType;
+
+
+parameter MYACK = 4'b0000,
+ MYNAK = 4'b0001,
+ MYSTALL = 4'b0010,
+ MYTOUT = 4'b0011,
+ MYIVRES = 4'b0100,
+ MYCRCER = 4'b0101;
+
+
+
+ begin
+
+
+ $display("%0d: USB Reset -----", $time);
+ `usbbfm.usbhw_reset;
+
+ address = 1;
+ endpt = 0;
+ $display("%0d: Set Address = %x -----", $time,address);
+ `usbbfm.SetAddress (address);
+ $display("%0d: Sending Setup Command ", $time);
+ `usbbfm.setup(7'h00, 4'h0, Status);
+ `usbbfm.printstatus(Status, MYACK);
+ $display("%0d: Sending Status Command ", $time);
+ `usbbfm.status_IN(7'h00, endpt, Status);
+ `usbbfm.printstatus(Status, MYACK);
+ #5000;
+
+ $display("%0d: Set configuration -----", $time);
+ `usbbfm.SetConfiguration(2'b01);
+ `usbbfm.setup(address, 4'b0000, Status);
+ `usbbfm.printstatus(Status, MYACK);
+ `usbbfm.status_IN(address, 4'b0000, Status);
+ `usbbfm.printstatus(Status, MYACK);
+ #2000;
+
+ $display("%0d: Configuration done !!!!!!", $time);
+ test_control.finish_test;
+
+ end
+
+endtask
diff --git a/verilog/dv/user_usb/tests/usb_test2.v b/verilog/dv/user_usb/tests/usb_test2.v
new file mode 100755
index 0000000..fe37549
--- /dev/null
+++ b/verilog/dv/user_usb/tests/usb_test2.v
@@ -0,0 +1,91 @@
+`define usbbfm u_usb_agent
+task usb_test2;
+
+reg [6:0] address;
+reg [3:0] endpt;
+reg [3:0] Status;
+
+ integer i,j;
+ reg [7:0] startbyte;
+ reg [15:0] mask;
+ integer MaxPktSize;
+ reg [3:0] PackType;
+
+
+parameter MYACK = 4'b0000,
+ MYNAK = 4'b0001,
+ MYSTALL = 4'b0010,
+ MYTOUT = 4'b0011,
+ MYIVRES = 4'b0100,
+ MYCRCER = 4'b0101;
+
+ begin
+ address = 7'b000_0001;
+ endpt = 4'b0000;
+
+ $display("%0d: USB Reset -----", $time);
+ `usbbfm.usbhw_reset;
+
+ $display("%0d: Set Address = 1 -----", $time);
+ `usbbfm.SetAddress (address);
+ `usbbfm.setup(7'h00, 4'h0, Status);
+ `usbbfm.printstatus(Status, MYACK);
+ `usbbfm.status_IN(7'h00, endpt, Status);
+ `usbbfm.printstatus(Status, MYACK);
+ #5000;
+
+ $display("%0d: Set configuration -----", $time);
+ `usbbfm.SetConfiguration(2'b01);
+ `usbbfm.setup(address, 4'b0000, Status);
+ `usbbfm.printstatus(Status, MYACK);
+ `usbbfm.status_IN(address, 4'b0000, Status);
+ `usbbfm.printstatus(Status, MYACK);
+ #2000;
+
+ $display("%0d: Configuration done !!!!!!", $time);
+
+ // write UART registers through USB
+
+ //////////////////////////////////////////////////////////////////
+
+
+ // register word write
+ $display("%0d: Performing Register Word Write------------", $time);
+ `usbbfm.VenRegWordWr (address, 32'h0, 32'h11223344);
+ `usbbfm.VenRegWordWr (address, 32'h4, 32'h22334455);
+ `usbbfm.VenRegWordWr (address, 32'h8, 32'h33445566);
+ `usbbfm.VenRegWordWr (address, 32'hC, 32'h44556677);
+ `usbbfm.VenRegWordWr (address, 32'h10, 32'h55667788);
+ `usbbfm.VenRegWordWr (address, 32'h14, 32'h66778899);
+ `usbbfm.VenRegWordWr (address, 32'h18, 32'h778899AA);
+ `usbbfm.VenRegWordWr (address, 32'h1C, 32'h8899AABB);
+ `usbbfm.VenRegWordWr (address, 32'h20, 32'h99AABBCC);
+ `usbbfm.VenRegWordWr (address, 32'h24, 32'hAABBCCDD);
+ `usbbfm.VenRegWordWr (address, 32'h28, 32'hBBCCDDEE);
+ `usbbfm.VenRegWordWr (address, 32'h2C, 32'hCCDDEEFF);
+ #500;
+
+ // register word Read
+ $display("%0d: Performing Register Word Read------------", $time);
+ `usbbfm.VenRegWordRdCmp (address, 32'h0 , 32'h11223344);
+ `usbbfm.VenRegWordRdCmp (address, 32'h4 , 32'h22334455);
+ `usbbfm.VenRegWordRdCmp (address, 32'h8 , 32'h33445566);
+ `usbbfm.VenRegWordRdCmp (address, 32'hC , 32'h44556677);
+ `usbbfm.VenRegWordRdCmp (address, 32'h10, 32'h55667788);
+ `usbbfm.VenRegWordRdCmp (address, 32'h14, 32'h66778899);
+ `usbbfm.VenRegWordRdCmp (address, 32'h18, 32'h778899AA);
+ `usbbfm.VenRegWordRdCmp (address, 32'h1C, 32'h8899AABB);
+ `usbbfm.VenRegWordRdCmp (address, 32'h20, 32'h99AABBCC);
+ `usbbfm.VenRegWordRdCmp (address, 32'h24, 32'hAABBCCDD);
+ `usbbfm.VenRegWordRdCmp (address, 32'h28, 32'hBBCCDDEE);
+ `usbbfm.VenRegWordRdCmp (address, 32'h2C, 32'hCCDDEEFF);
+ #500
+
+
+
+ $display ("USB doing register writes and reads to USB block end \n");
+
+ test_control.finish_test;
+ end
+
+endtask
diff --git a/verilog/dv/user_usb/tests/usb_test3.v b/verilog/dv/user_usb/tests/usb_test3.v
new file mode 100755
index 0000000..51d1c69
--- /dev/null
+++ b/verilog/dv/user_usb/tests/usb_test3.v
@@ -0,0 +1,182 @@
+`define usbbfm tb_top.u_usb_agent
+task usb_test3;
+
+reg [6:0] address;
+reg [3:0] endpt;
+reg [3:0] Status;
+reg [31:0] ByteCount;
+reg [31:0] ReadData;
+integer i,j,k;
+
+
+reg [1:0] data_bit ;
+reg stop_bits ; // 0: 1 stop bit; 1: 2 stop bit;
+reg stick_parity ; // 1: force even parity
+reg parity_en ; // parity enable
+reg even_odd_parity ; // 0: odd parity; 1: even parity
+reg [15:0] divisor ; // divided by (n+1) * 16
+reg [15:0] timeout ;// wait time limit
+reg fifo_enable ; // fifo mode disable
+
+reg [7:0] write_data [0:39];
+reg [15:0] rx_nu;
+reg [15:0] tx_nu;
+
+
+parameter MYACK = 4'b0000,
+ MYNAK = 4'b0001,
+ MYSTALL = 4'b0010,
+ MYTOUT = 4'b0011,
+ MYIVRES = 4'b0100,
+ MYCRCER = 4'b0101;
+
+ begin
+ address = 7'b000_0001;
+ endpt = 4'b0000;
+
+ $display("%0d: USB Reset -----", $time);
+ `usbbfm.usbhw_reset;
+
+ /*********************************************************
+ * HOST DEVICE
+ * 1. 0x2D,0x00, 0x00
+ * 2. 0xC3,0x00,0x05,0x01,
+ * 0x00,0x00,0x00,0x00,
+ * 0x00,0xEB,0x25
+ * 3. 0xD2
+ * 4. 0x69,0x00, 0x10
+ * 5. 0x4B, 0x00
+ * 6. 0xD2
+ **********************************************************/
+ $display("%0d: Set Address = 1 -----", $time);
+ `usbbfm.SetAddress (address);
+ `usbbfm.setup(7'h00, 4'h0, Status);
+ `usbbfm.printstatus(Status, MYACK);
+ `usbbfm.status_IN(7'h00, endpt, Status);
+ `usbbfm.printstatus(Status, MYACK);
+
+ #5000;
+ /*********************************************************
+ * HOST DEVICE
+ * 1. 0x2D,0x01, 0xE8
+ * 2. 0xC3,0x00,0x09,0x01,
+ * 0x00,0x00,0x00,0x00,
+ * 0x00,0x27,0x25
+ * 3. 0xD2
+ * 4. 0x69,0x01, 0xE8
+ * 5. 0x4B, 0x00
+ * 6. 0xD2
+ **********************************************************/
+
+ $display("%0d: Set configuration -----", $time);
+ `usbbfm.SetConfiguration(2'b01);
+ `usbbfm.setup(address, 4'b0000, Status);
+ `usbbfm.printstatus(Status, MYACK);
+ `usbbfm.status_IN(address, 4'b0000, Status);
+ `usbbfm.printstatus(Status, MYACK);
+ #2000;
+
+ $display("%0d: Configuration done !!!!!!", $time);
+
+ // write UART registers through USB
+
+ //////////////////////////////////////////////////////////////////
+ data_bit = 2'b11;
+ stop_bits = 0; // 0: 1 stop bit; 1: 2 stop bit;
+ stick_parity = 0; // 1: force even parity
+ parity_en = 1; // parity enable
+ even_odd_parity = 1; // 0: odd parity; 1: even parity
+ divisor = 15; // divided by (n+1) * 16
+ timeout = 500;// wait time limit
+ fifo_enable = 0; // fifo mode disable
+
+ tb_top.u_uart_agent.uart_init;
+ /*********************************************************
+ * HOST DEVICE
+ * 1. 0x2D,0x01, 0xE8
+ * 2. 0xC3,0x40,0x10,0x00,
+ * 0x00,0x00,0x00,0x04,
+ * 0x00,0xA8,0xC5
+ * 3. 0xD2
+ * 4. 0xE1,0x01, 0xE8
+ * 5. 0x4B,0x00,0x00,0x00
+ * 0x17,0xBF,0xD5
+ * 6 0xD2
+ * 7. 0x69,0x01,0xE8
+ * 8. 0x4B,0x00
+ * 9. 0xD2
+ **********************************************************/
+ `usbbfm.VenRegWordWr (address, 32'h0, {27'h0,2'b10,1'b1,1'b1,1'b1});
+ /*********************************************************
+ * HOST DEVICE
+ * 1. 0x2D,0x01, 0xE8
+ * 2. 0xC3,0x40,0x10,0x00,
+ * 0x00,0x00,0x08,0x04,
+ * 0x00,0x29,0x07
+ * 3. 0xD2
+ * 4. 0xE1,0x01, 0xE8
+ * 5. 0x4B,0x00,0x00,0x00
+ * 0x0E,0x7E,0x1F
+ * 6 0xD2
+ * 7. 0x69,0x01,0xE8
+ * 8. 0x4B,0x00
+ * 9. 0xD2
+ **********************************************************/
+ // Baud Clock 16x, Master Clock/ (2+cfg_value)
+ `usbbfm.VenRegWordWr (address, 32'h8, divisor-1);
+ tb_top.u_uart_agent.control_setup (data_bit, stop_bits, parity_en, even_odd_parity, stick_parity, timeout, divisor, fifo_enable);
+
+ for (i=0; i<40; i=i+1)
+ write_data[i] = $random;
+
+ fork
+ begin
+ for (i=0; i<40; i=i+1)
+ begin
+ $display ("\n... Writing char %d ...", write_data[i]);
+ tb_top.u_uart_agent.write_char (write_data[i]);
+ #20000;
+ end
+ end
+
+ begin
+ for (j=0; j<40; j=j+1)
+ begin
+ tb_top.u_uart_agent.read_char_chk(write_data[j]);
+ end
+ end
+
+ // Read through the USB and check the UART RX Fifo Status;
+ // If Available, then loop it back
+ begin
+ for (k=0; k<40; k=k+1)
+ begin
+ ReadData[1]= 1'b1;
+ while(ReadData[1] == 1'b1 ) begin // Check for UART RX fifo not empty
+ $display ("\n... Reading the UART Status: %x ...", ReadData);
+ /*********************************************************
+ * HOST DEVICE
+ * 1. 0x2D,0x01, 0xE8
+ * 2. 0xC3,0xC0,0x11,0x00,
+ * 0x00,0x00,0x0C,0x04,
+ * 0x00,0x70,0x66
+ * 3. 0xD2
+ * 4. 0x69,0x01, 0xE8
+ * 5. 0x4B,00
+ * 6. 0xD2
+ * 7. 0xE1,0x01,0xE8
+ * 8. 0x4B,0x00, 0x00
+ * 9 0xD2
+ **********************************************************/
+ `usbbfm.VenRegWordRd (address, 32'hC, ReadData);
+ end
+ `usbbfm.VenRegWordRd (address, 32'h14, ReadData); // Read the UART RXD Data
+ `usbbfm.VenRegWordWr (address, 32'h10, ReadData); // Write Back to UART TXD
+ end
+ end
+ join
+
+ #100
+ tb_top.u_uart_agent.report_status(rx_nu, tx_nu);
+end
+endtask
diff --git a/verilog/dv/user_usb/user_usb_tb.v b/verilog/dv/user_usb/user_usb_tb.v
new file mode 100644
index 0000000..73e2b47
--- /dev/null
+++ b/verilog/dv/user_usb/user_usb_tb.v
@@ -0,0 +1,561 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// 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.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Standalone User validation Test bench ////
+//// ////
+//// This file is part of the riscduino project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// This is a standalone test bench to validate the ////
+//// usb interfaface through External WB i/F. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 09 Mar 2022, Dinesh A ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ns
+
+// Note in caravel, 0x30XX_XXXX only come to user interface
+// So, using wb_host bank select we have changing MSB address [31:24] = 0x10
+`define ADDR_SPACE_UART 32'h3001_0000
+`define ADDR_SPACE_USB 32'h3001_0080
+`define ADDR_SPACE_SSPI 32'h3001_00C0
+`define ADDR_SPACE_PINMUX 32'h3002_0000
+
+`define TB_GLBL user_usb_tb
+`define USB_BFM u_usb_agent
+
+`include "uprj_netlists.v"
+`include "usb_agents.v"
+`include "test_control.v"
+`include "usb1d_defines.v"
+`include "usbd_files.v"
+
+module user_usb_tb;
+
+parameter USB_HPER = 10.4167; // 48Mhz Half cycle
+parameter USER2_HPER = 2.6042; // 192Mhz Half cycle
+
+ reg clock;
+ reg user_clock2;
+ reg usb_48mhz_clk;
+ reg wb_rst_i;
+ reg power1, power2;
+ reg power3, power4;
+
+ reg wbd_ext_cyc_i; // strobe/request
+ reg wbd_ext_stb_i; // strobe/request
+ reg [31:0] wbd_ext_adr_i; // address
+ reg wbd_ext_we_i; // write
+ reg [31:0] wbd_ext_dat_i; // data output
+ reg [3:0] wbd_ext_sel_i; // byte enable
+
+ wire [31:0] wbd_ext_dat_o; // data input
+ wire wbd_ext_ack_o; // acknowlegement
+ wire wbd_ext_err_o; // error
+
+ // User I/O
+ wire [37:0] io_oeb;
+ wire [37:0] io_out;
+ wire [37:0] io_in;
+
+
+ reg [1:0] spi_chip_no;
+
+ wire gpio;
+ wire [37:0] mprj_io;
+ wire [7:0] mprj_io_0;
+ reg test_fail;
+ reg [31:0] read_data;
+
+ //-----------------------------------
+ // Register Interface
+ // ----------------------------------
+ wire [31:0] usbd_reg_addr; // Register Address
+ wire usbd_reg_rdwrn; // 0 -> write, 1-> read
+ wire usbd_reg_req; // Register Req
+ wire [31:0] usbd_reg_wdata; // Register write data
+ reg [31:0] usbd_reg_rdata; // Register Read Data
+ reg usbd_reg_ack = 1'b1; // Register Ack
+
+ reg [31:0] RegBank [0:15];
+
+ // External clock is used by default. Make this artificially fast for the
+ // simulation. Normally this would be a slow clock and the digital PLL
+ // would be the fast clock.
+
+ always #12.5 clock <= (clock === 1'b0);
+
+ // 48Mhz clock generation
+ always begin
+ #USB_HPER usb_48mhz_clk = 1'b0;
+ #USB_HPER usb_48mhz_clk = 1'b1;
+ end
+
+ // USER Clock generation
+ always begin
+ #USER2_HPER user_clock2 = 1'b0;
+ #USER2_HPER user_clock2 = 1'b1;
+ end
+
+ initial begin
+ clock = 0;
+ wbd_ext_cyc_i ='h0; // strobe/request
+ wbd_ext_stb_i ='h0; // strobe/request
+ wbd_ext_adr_i ='h0; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='h0; // data output
+ wbd_ext_sel_i ='h0; // byte enable
+ end
+ initial begin
+ wb_rst_i <= 1'b1;
+ #100;
+ wb_rst_i <= 1'b0; // Release reset
+ end
+
+ `ifdef WFDUMP
+ initial begin
+ $dumpfile("simx.vcd");
+ $dumpvars(5, user_usb_tb);
+ end
+ `endif
+
+ always@(posedge wb_rst_i or posedge usb_48mhz_clk)
+ begin
+ if(wb_rst_i == 1'b1) begin
+ usbd_reg_rdata = 'h0;
+ usbd_reg_ack = 'h0;
+ end else begin
+ if(usbd_reg_req && usbd_reg_rdwrn == 1'b0 && !usbd_reg_ack) begin
+ usbd_reg_ack = 'h1;
+ RegBank[usbd_reg_addr[5:2]] = usbd_reg_wdata;
+ $display("STATUS: Write Access Address : %x Data: %x",usbd_reg_addr[7:0],usbd_reg_wdata);
+ end else if(usbd_reg_req && usbd_reg_rdwrn == 1'b1 && !usbd_reg_ack) begin
+ usbd_reg_ack = 'h1;
+ usbd_reg_rdata = RegBank[usbd_reg_addr[5:2]];
+ $display("STATUS: Read Access Address : %x Data: %x",usbd_reg_addr[7:0],usbd_reg_rdata);
+ end else begin
+ usbd_reg_ack = 'h0;
+ end
+ end
+ end
+
+ initial begin
+ $dumpon;
+
+ #200; // Wait for reset removal
+ repeat (10) @(posedge clock);
+ $display("Monitor: Standalone User Risc Boot Test Started");
+
+ // Remove Wb Reset
+ wb_user_core_write('h3080_0000,'h1);
+
+ // Enable SPI Multi Functional Ports
+ wb_user_core_write(`ADDR_SPACE_PINMUX+'h0038,'h400);
+
+ repeat (2) @(posedge clock);
+ #1;
+
+ // Set USB clock : 192/4 = 48Mhz
+ wb_user_core_write('h3080_0000,{8'h82,4'h0,8'h0,4'h0,8'h01});
+
+ // Remove the reset
+ // Remove WB and SPI/UART Reset, Keep CORE under Reset
+ wb_user_core_write(`ADDR_SPACE_PINMUX+8'h8,'h03F);
+
+
+ test_fail = 0;
+ repeat (200) @(posedge clock);
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+
+
+ //usb_test1;
+ usb_test2;
+
+
+ repeat (100) @(posedge clock);
+ // $display("+1000 cycles");
+
+ if(test_control.error_count == 0) begin
+ `ifdef GL
+ $display("Monitor: USB Mode (GL) Passed");
+ `else
+ $display("Monitor: USB Mode (RTL) Passed");
+ `endif
+ end else begin
+ `ifdef GL
+ $display("Monitor: USB Mode (GL) Failed");
+ `else
+ $display("Monitor: USB Mode (RTL) Failed");
+ `endif
+ end
+ $display("###################################################");
+ $finish;
+ end
+
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+ .vccd1(USER_VDD1V8), // User area 1 1.8V supply
+ .vssd1(VSS), // User area 1 digital ground
+`endif
+ .wb_clk_i (clock ), // System clock
+ .user_clock2 (user_clock2 ), // Real-time clock
+ .wb_rst_i (wb_rst_i ), // Regular Reset signal
+
+ .wbs_cyc_i (wbd_ext_cyc_i), // strobe/request
+ .wbs_stb_i (wbd_ext_stb_i), // strobe/request
+ .wbs_adr_i (wbd_ext_adr_i), // address
+ .wbs_we_i (wbd_ext_we_i), // write
+ .wbs_dat_i (wbd_ext_dat_i), // data output
+ .wbs_sel_i (wbd_ext_sel_i), // byte enable
+
+ .wbs_dat_o (wbd_ext_dat_o), // data input
+ .wbs_ack_o (wbd_ext_ack_o), // acknowlegement
+
+
+ // Logic Analyzer Signals
+ .la_data_in ('1) ,
+ .la_data_out (),
+ .la_oenb ('0),
+
+
+ // IOs
+ .io_in (io_in) ,
+ .io_out (io_out) ,
+ .io_oeb (io_oeb) ,
+
+ .user_irq ()
+
+);
+ usb_agent u_usb_agent();
+ test_control test_control();
+
+`ifndef GL // Drive Power for Hold Fix Buf
+ // All standard cell need power hook-up for functionality work
+ initial begin
+
+ end
+`endif
+
+// Drive USB Pads
+//
+tri usbd_txdp = (io_oeb[36] == 1'b0) ? io_out[36] : 1'bz;
+tri usbd_txdn = (io_oeb[37] == 1'b0) ? io_out[37] : 1'bz;
+
+assign io_in[36] = usbd_txdp;
+assign io_in[37] = usbd_txdn;
+
+// Full Speed Device Indication
+
+pullup(usbd_txdp);
+//pulldown(usbd_txdn);
+
+usb1d_top u_usb_top(
+
+ .clk_i (usb_48mhz_clk),
+ .rstn_i (!wb_rst_i),
+
+ // USB PHY Interface
+ .usb_dp (usbd_txdp),
+ .usb_dn (usbd_txdn),
+
+ // USB Misc
+ .phy_tx_mode (1'b1),
+ .usb_rst (),
+
+ // Interrupts
+ .dropped_frame (),
+ .misaligned_frame(),
+ .crc16_err (),
+
+ // Vendor Features
+ .v_set_int (),
+ .v_set_feature (),
+ .wValue (),
+ .wIndex (),
+ .vendor_data (),
+
+ // USB Status
+ .usb_busy (),
+ .ep_sel (),
+
+ // End point 1 configuration
+ .ep1_cfg ( `ISO | `IN | 14'd0256 ),
+ // End point 1 'OUT' FIFO i/f
+ .ep1_dout ( ),
+ .ep1_we ( ),
+ .ep1_full ( 1'b0 ),
+ // End point 1 'IN' FIFO i/f
+ .ep1_din ( 8'h0 ),
+ .ep1_re ( ),
+ .ep1_empty ( 1'b0 ),
+ .ep1_bf_en ( 1'b0 ),
+ .ep1_bf_size ( 7'h0 ),
+
+ // End point 2 configuration
+ .ep2_cfg ( `ISO | `OUT | 14'd0256 ),
+ // End point 2 'OUT' FIFO i/f
+ .ep2_dout ( ),
+ .ep2_we ( ),
+ .ep2_full ( 1'b0 ),
+ // End point 2 'IN' FIFO i/f
+ .ep2_din ( 8'h0 ),
+ .ep2_re ( ),
+ .ep2_empty ( 1'b0 ),
+ .ep2_bf_en ( 1'b0 ),
+ .ep2_bf_size ( 7'h0 ),
+
+ // End point 3 configuration
+ .ep3_cfg ( `BULK | `IN | 14'd064 ),
+ // End point 3 'OUT' FIFO i/f
+ .ep3_dout ( ),
+ .ep3_we ( ),
+ .ep3_full ( 1'b0 ),
+ // End point 3 'IN' FIFO i/f
+ .ep3_din ( 8'h0 ),
+ .ep3_re ( ),
+ .ep3_empty ( 1'b0 ),
+ .ep3_bf_en ( 1'b0 ),
+ .ep3_bf_size ( 7'h0 ),
+
+ // End point 4 configuration
+ .ep4_cfg ( `BULK | `OUT | 14'd064 ),
+ // End point 4 'OUT' FIFO i/f
+ .ep4_dout ( ),
+ .ep4_we ( ),
+ .ep4_full ( 1'b0 ),
+ // End point 4 'IN' FIFO i/f
+ .ep4_din ( 8'h0 ),
+ .ep4_re ( ),
+ .ep4_empty ( 1'b0 ),
+ .ep4_bf_en ( 1'b0 ),
+ .ep4_bf_size ( 7'h0 ),
+
+ // End point 5 configuration
+ .ep5_cfg ( `INT | `IN | 14'd064 ),
+ // End point 5 'OUT' FIFO i/f
+ .ep5_dout ( ),
+ .ep5_we ( ),
+ .ep5_full ( 1'b0 ),
+ // End point 5 'IN' FIFO i/f
+ .ep5_din ( 8'h0 ),
+ .ep5_re ( ),
+ .ep5_empty ( 1'b0 ),
+ .ep5_bf_en ( 1'b0 ),
+ .ep5_bf_size ( 7'h0 ),
+
+ // End point 6 configuration
+ .ep6_cfg ( 14'h00 ),
+ // End point 6 'OUT' FIFO i/f
+ .ep6_dout ( ),
+ .ep6_we ( ),
+ .ep6_full ( 1'b0 ),
+ // End point 6 'IN' FIFO i/f
+ .ep6_din ( 8'h0 ),
+ .ep6_re ( ),
+ .ep6_empty ( 1'b0 ),
+ .ep6_bf_en ( 1'b0 ),
+ .ep6_bf_size ( 7'h0 ),
+
+ // End point 7 configuration
+ .ep7_cfg ( 14'h00 ),
+ // End point 7 'OUT' FIFO i/f
+ .ep7_dout ( ),
+ .ep7_we ( ),
+ .ep7_full ( 1'b0 ),
+ // End point 7 'IN' FIFO i/f
+ .ep7_din ( 8'h0 ),
+ .ep7_re ( ),
+ .ep7_empty ( 1'b0 ),
+ .ep7_bf_en ( 1'b0 ),
+ .ep7_bf_size ( 7'h0 ),
+
+ // Register Interface
+ .reg_addr (usbd_reg_addr),
+ .reg_rdwrn (usbd_reg_rdwrn),
+ .reg_req (usbd_reg_req),
+ .reg_wdata (usbd_reg_wdata),
+ .reg_rdata (usbd_reg_rdata),
+ .reg_ack (usbd_reg_ack)
+
+ );
+
+
+//----------------------------------------------------
+// Task
+// --------------------------------------------------
+task test_err;
+begin
+ test_fail = 1;
+end
+endtask
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+ repeat (1) @(posedge clock);
+ #1;
+ wbd_ext_adr_i =address; // address
+ wbd_ext_we_i ='h1; // write
+ wbd_ext_dat_i =data; // data output
+ wbd_ext_sel_i ='hF; // byte enable
+ wbd_ext_cyc_i ='h1; // strobe/request
+ wbd_ext_stb_i ='h1; // strobe/request
+ wait(wbd_ext_ack_o == 1);
+ repeat (1) @(posedge clock);
+ #1;
+ wbd_ext_cyc_i ='h0; // strobe/request
+ wbd_ext_stb_i ='h0; // strobe/request
+ wbd_ext_adr_i ='h0; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='h0; // data output
+ wbd_ext_sel_i ='h0; // byte enable
+ $display("STATUS: WB USER ACCESS WRITE Address : 0x%x, Data : 0x%x",address,data);
+ repeat (2) @(posedge clock);
+end
+endtask
+
+task wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg [31:0] data;
+begin
+ repeat (1) @(posedge clock);
+ #1;
+ wbd_ext_adr_i =address; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='0; // data output
+ wbd_ext_sel_i ='hF; // byte enable
+ wbd_ext_cyc_i ='h1; // strobe/request
+ wbd_ext_stb_i ='h1; // strobe/request
+ wait(wbd_ext_ack_o == 1);
+ data = wbd_ext_dat_o;
+ repeat (1) @(posedge clock);
+ #1;
+ wbd_ext_cyc_i ='h0; // strobe/request
+ wbd_ext_stb_i ='h0; // strobe/request
+ wbd_ext_adr_i ='h0; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='h0; // data output
+ wbd_ext_sel_i ='h0; // byte enable
+ //$display("STATUS: WB USER ACCESS READ Address : 0x%x, Data : 0x%x",address,data);
+ repeat (2) @(posedge clock);
+end
+endtask
+
+task wb_user_core_read_check;
+input [31:0] address;
+output [31:0] data;
+input [31:0] cmp_data;
+reg [31:0] data;
+begin
+ repeat (1) @(posedge clock);
+ #1;
+ wbd_ext_adr_i =address; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='0; // data output
+ wbd_ext_sel_i ='hF; // byte enable
+ wbd_ext_cyc_i ='h1; // strobe/request
+ wbd_ext_stb_i ='h1; // strobe/request
+ wait(wbd_ext_ack_o == 1);
+ data = wbd_ext_dat_o;
+ repeat (1) @(posedge clock);
+ #1;
+ wbd_ext_cyc_i ='h0; // strobe/request
+ wbd_ext_stb_i ='h0; // strobe/request
+ wbd_ext_adr_i ='h0; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='h0; // data output
+ wbd_ext_sel_i ='h0; // byte enable
+ if(data !== cmp_data) begin
+ $display("ERROR : WB USER ACCESS READ Address : 0x%x, Exd: 0x%x Rxd: 0x%x ",address,cmp_data,data);
+ user_usb_tb.test_fail = 1;
+ end else begin
+ $display("STATUS: WB USER ACCESS READ Address : 0x%x, Data : 0x%x",address,data);
+ end
+ repeat (2) @(posedge clock);
+end
+endtask
+
+
+`ifdef GL
+
+wire wbd_spi_stb_i = u_top.u_spi_master.wbd_stb_i;
+wire wbd_spi_ack_o = u_top.u_spi_master.wbd_ack_o;
+wire wbd_spi_we_i = u_top.u_spi_master.wbd_we_i;
+wire [31:0] wbd_spi_adr_i = u_top.u_spi_master.wbd_adr_i;
+wire [31:0] wbd_spi_dat_i = u_top.u_spi_master.wbd_dat_i;
+wire [31:0] wbd_spi_dat_o = u_top.u_spi_master.wbd_dat_o;
+wire [3:0] wbd_spi_sel_i = u_top.u_spi_master.wbd_sel_i;
+
+wire wbd_sdram_stb_i = u_top.u_sdram_ctrl.wb_stb_i;
+wire wbd_sdram_ack_o = u_top.u_sdram_ctrl.wb_ack_o;
+wire wbd_sdram_we_i = u_top.u_sdram_ctrl.wb_we_i;
+wire [31:0] wbd_sdram_adr_i = u_top.u_sdram_ctrl.wb_addr_i;
+wire [31:0] wbd_sdram_dat_i = u_top.u_sdram_ctrl.wb_dat_i;
+wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
+wire [3:0] wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
+
+wire wbd_uart_stb_i = u_top.u_uart_i2c_usb.reg_cs;
+wire wbd_uart_ack_o = u_top.u_uart_i2c_usb.reg_ack;
+wire wbd_uart_we_i = u_top.u_uart_i2c_usb.reg_wr;
+wire [7:0] wbd_uart_adr_i = u_top.u_uart_i2c_usb.reg_addr;
+wire [7:0] wbd_uart_dat_i = u_top.u_uart_i2c_usb.reg_wdata;
+wire [7:0] wbd_uart_dat_o = u_top.u_uart_i2c_usb.reg_rdata;
+wire wbd_uart_sel_i = u_top.u_uart_i2c_usb.reg_be;
+
+`endif
+
+/**
+`ifdef GL
+//-----------------------------------------------------------------------------
+// RISC IMEM amd DMEM Monitoring TASK
+//-----------------------------------------------------------------------------
+
+`define RISC_CORE user_uart_tb.u_top.u_core.u_riscv_top
+
+always@(posedge `RISC_CORE.wb_clk) begin
+ if(`RISC_CORE.wbd_imem_ack_i)
+ $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x", `RISC_CORE.wbd_imem_adr_o,`RISC_CORE.wbd_imem_dat_i);
+ if(`RISC_CORE.wbd_dmem_ack_i && `RISC_CORE.wbd_dmem_we_o)
+ $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_o);
+ if(`RISC_CORE.wbd_dmem_ack_i && !`RISC_CORE.wbd_dmem_we_o)
+ $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_i);
+end
+
+`endif
+**/
+`include "tests/usb_test1.v"
+`include "tests/usb_test2.v"
+
+endmodule
+`default_nettype wire