Added management flash SPI pass-through mode testbench and debugged it.
diff --git a/verilog/dv/caravel/mgmt_soc/Makefile b/verilog/dv/caravel/mgmt_soc/Makefile
index 9f185c0..b2e847d 100644
--- a/verilog/dv/caravel/mgmt_soc/Makefile
+++ b/verilog/dv/caravel/mgmt_soc/Makefile
@@ -3,7 +3,7 @@
.SUFFIXES:
.SILENT: clean all
-PATTERNS = gpio mem uart perf hkspi sysctrl mprj_ctrl
+PATTERNS = gpio mem uart perf hkspi sysctrl mprj_ctrl pass_thru timer
all: ${PATTERNS}
for i in ${PATTERNS}; do \
diff --git a/verilog/dv/caravel/mgmt_soc/pass_thru/Makefile b/verilog/dv/caravel/mgmt_soc/pass_thru/Makefile
new file mode 100644
index 0000000..32d51ce
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pass_thru/Makefile
@@ -0,0 +1,41 @@
+# ---- Test patterns for project striVe ----
+FIRMWARE_PATH = ../..
+RTL_PATH = ../../../../rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH=/ef/apps/bin
+
+.SUFFIXES:
+
+PATTERN = pass_thru
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS)-I $(IP_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/riscv32-unknown-elf-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/riscv32-unknown-elf-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+ rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
+
diff --git a/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru.c b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru.c
new file mode 100644
index 0000000..d31b31f
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru.c
@@ -0,0 +1,74 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+void putchar(char c)
+{
+ if (c == '\n')
+ putchar('\r');
+ reg_uart_data = c;
+}
+
+void print(const char *p)
+{
+ while (*p)
+ putchar(*(p++));
+}
+
+// --------------------------------------------------------
+
+void main()
+{
+ // This program is just to keep the processor busy while the
+ // housekeeping SPI is being accessed. to show that the
+ // processor is halted while the SPI is accessing the
+ // flash SPI in pass-through mode.
+
+ // Configure I/O: High 16 bits of user area used for a 16-bit
+ // word to write and be detected by the testbench verilog.
+ // Only serial Tx line is used in this testbench. It connects
+ // to mprj_io[6]. Since all lines of the chip are input or
+ // high impedence on startup, the I/O has to be configured
+ // for output
+
+ reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+ reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+ reg_mprj_io_6 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+ // Apply configuration
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ // Start test
+ reg_mprj_datal = 0xa0000000;
+
+ // Set clock to 64 kbaud and enable the UART
+ reg_uart_clkdiv = 625;
+ reg_uart_enable = 1;
+
+ // Test in progress
+ reg_mprj_datal = 0xa5000000;
+
+ // Test message
+ print("Test message\n");
+
+ // End test
+ reg_mprj_datal = 0xab000000;
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru_tb.v b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru_tb.v
new file mode 100644
index 0000000..e00c85f
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru_tb.v
@@ -0,0 +1,258 @@
+/*
+ * StriVe housekeeping pass-thru mode SPI testbench.
+ */
+
+`timescale 1 ns / 1 ps
+
+`include "caravel.v"
+`include "spiflash.v"
+`include "tbuart.v"
+
+module pass_thru_tb;
+ reg clock;
+ reg SDI, CSB, SCK, RSTB;
+
+ wire gpio;
+ wire [15:0] checkbits;
+ wire [36:0] mprj_io;
+ wire uart_tx;
+ wire uart_rx;
+
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+ wire flash_io2;
+ wire flash_io3;
+
+ wire SDO;
+
+ always #10 clock <= (clock === 1'b0);
+
+ initial begin
+ clock = 0;
+ end
+
+ // The main testbench is here. Put the housekeeping SPI into
+ // pass-thru mode and read several bytes from the flash SPI.
+
+ // First define tasks for SPI functions
+
+ task start_csb;
+ begin
+ SCK <= 1'b0;
+ SDI <= 1'b0;
+ CSB <= 1'b0;
+ #50;
+ end
+ endtask
+
+ task end_csb;
+ begin
+ SCK <= 1'b0;
+ SDI <= 1'b0;
+ CSB <= 1'b1;
+ #50;
+ end
+ endtask
+
+ task write_byte;
+ input [7:0] odata;
+ begin
+ SCK <= 1'b0;
+ for (i=7; i >= 0; i--) begin
+ #50;
+ SDI <= odata[i];
+ #50;
+ SCK <= 1'b1;
+ #100;
+ SCK <= 1'b0;
+ end
+ end
+ endtask
+
+ task read_byte;
+ output [7:0] idata;
+ begin
+ SCK <= 1'b0;
+ SDI <= 1'b0;
+ for (i=7; i >= 0; i--) begin
+ #50;
+ idata[i] = SDO;
+ #50;
+ SCK <= 1'b1;
+ #100;
+ SCK <= 1'b0;
+ end
+ end
+ endtask
+
+ task read_write_byte
+ (input [7:0] odata,
+ output [7:0] idata);
+ begin
+ SCK <= 1'b0;
+ for (i=7; i >= 0; i--) begin
+ #50;
+ SDI <= odata[i];
+ idata[i] = SDO;
+ #50;
+ SCK <= 1'b1;
+ #100;
+ SCK <= 1'b0;
+ end
+ end
+ endtask
+
+ integer i;
+
+ // Now drive the digital signals on the housekeeping SPI
+ reg [7:0] tbdata;
+
+ initial begin
+ $dumpfile("pass_thru.vcd");
+ $dumpvars(0, pass_thru_tb);
+
+ CSB <= 1'b1;
+ SCK <= 1'b0;
+ SDI <= 1'b0;
+ RSTB <= 1'b0;
+
+ #2000;
+
+ RSTB <= 1'b1;
+
+ // Wait on start of program execution
+ wait(checkbits == 16'hA000);
+
+ // First do a normal read from the housekeeping SPI to
+ // make sure the housekeeping SPI works.
+
+ start_csb();
+ write_byte(8'h40); // Read stream command
+ write_byte(8'h03); // Address (register 3 = product ID)
+ read_byte(tbdata);
+ end_csb();
+ #10;
+ $display("Read data = 0x%02x (should be 0x10)", tbdata);
+ if(tbdata !== 8'h10) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+
+ start_csb();
+ write_byte(8'hc4); // Pass-thru mode
+ write_byte(8'h03); // Command 03 (read values w/3-byte address
+ write_byte(8'h00); // Address is next three bytes (0x000000)
+ write_byte(8'h00);
+ write_byte(8'h00);
+
+ read_byte(tbdata);
+ $display("Read flash data = 0x%02x (should be 0x93)", tbdata);
+ if(tbdata !== 8'h93) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read flash data = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read flash data = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read flash data = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read flash data = 0x%02x (should be 0x93)", tbdata);
+ if(tbdata !== 8'h93) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read flash data = 0x%02x (should be 0x01)", tbdata);
+ if(tbdata !== 8'h01) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read flash data = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read flash data = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+
+ end_csb();
+
+ // Wait for processor to restart
+ wait(checkbits == 16'hA000);
+
+ // Read product ID register again
+
+ start_csb();
+ write_byte(8'h40); // Read stream command
+ write_byte(8'h03); // Address (register 3 = product ID)
+ read_byte(tbdata);
+ end_csb();
+ #10;
+ $display("Read data = 0x%02x (should be 0x10)", tbdata);
+ if(tbdata !== 8'h10) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+
+ $display("Monitor: Test HK SPI (RTL) Passed");
+
+ #10000;
+ $finish;
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VDD3V3 = 1'b1;
+ assign VSS = 1'b0;
+ assign VDD1V8 = 1'b1;
+
+ wire hk_sck;
+ wire hk_csb;
+ wire hk_sdi;
+
+ assign hk_sck = SCK;
+ assign hk_csb = CSB;
+ assign hk_sdi = SDI;
+
+ assign checkbits = mprj_io[31:16];
+ assign uart_tx = mprj_io[6];
+ assign mprj_io[5] = uart_rx;
+ assign mprj_io[4] = hk_sck;
+ assign mprj_io[3] = hk_csb;
+ assign mprj_io[2] = hk_sdi;
+ assign SDO = mprj_io[1];
+
+ caravel uut (
+ .vddio (VDD3V3),
+ .vssio (VSS),
+ .vdda (VDD3V3),
+ .vssa (VSS),
+ .vccd (VDD1V8),
+ .vssd (VSS),
+ .vdda1 (VDD3V3),
+ .vdda2 (VDD3V3),
+ .vssa1 (VSS),
+ .vssa2 (VSS),
+ .vccd1 (VDD1V8),
+ .vccd2 (VDD1V8),
+ .vssd1 (VSS),
+ .vssd2 (VSS),
+ .clock (clock),
+ .gpio (gpio),
+ .mprj_io (mprj_io),
+ .flash_csb(flash_csb),
+ .flash_clk(flash_clk),
+ .flash_io0(flash_io0),
+ .flash_io1(flash_io1),
+ .resetb (RSTB)
+ );
+
+ spiflash #(
+ .FILENAME("pass_thru.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+ tbuart tbuart (
+ .ser_rx(uart_tx)
+ );
+
+endmodule
diff --git a/verilog/dv/caravel/mgmt_soc/timer/Makefile b/verilog/dv/caravel/mgmt_soc/timer/Makefile
new file mode 100644
index 0000000..a7a81eb
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer/Makefile
@@ -0,0 +1,40 @@
+FIRMWARE_PATH = ../..
+RTL_PATH = ../../../../rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH=/ef/apps/bin
+
+.SUFFIXES:
+
+PATTERN = timer
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS)-I $(IP_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/riscv32-unknown-elf-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/riscv32-unknown-elf-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+ rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
+
diff --git a/verilog/dv/caravel/mgmt_soc/timer/timer.c b/verilog/dv/caravel/mgmt_soc/timer/timer.c
new file mode 100644
index 0000000..ed74567
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer/timer.c
@@ -0,0 +1,95 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+/*
+ * Timer Test
+ */
+
+void main()
+{
+ int i;
+
+ /* Set data out to zero */
+ reg_mprj_datal = 0;
+
+ /* Lower 8 pins are input and upper 8 pins are output */
+ reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+ reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+ reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+ reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+ reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+ reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+ reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+ reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+ reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ // change the pull up and pull down (checked by the TB)
+ reg_mprj_datal = 0xa0000000;
+
+ reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+ reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+ reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+ reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+
+ reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+ reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+ reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+ reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ reg_mprj_datal = 0x0b000000;
+
+ reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+ reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+ reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+ reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+
+ reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+ reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+ reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+ reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+ reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+ reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+ reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+
+ reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+ reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+ reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+ reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ // read the lower 8 pins, add 1 then output the result
+ // checked by the TB
+ reg_mprj_datal = 0xab000000;
+
+ while (1){
+ int x = (reg_mprj_datal & 0xff0000) >> 16;
+ reg_mprj_datal = (x+1) << 24;
+ }
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/timer/timer_tb.v b/verilog/dv/caravel/mgmt_soc/timer/timer_tb.v
new file mode 100644
index 0000000..0cc67fd
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer/timer_tb.v
@@ -0,0 +1,168 @@
+/*
+ * StriVe - A full example SoC using PicoRV32 in SkyWater s8
+ *
+ * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
+ * Copyright (C) 2018 Tim Edwards <tim@efabless.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+`timescale 1 ns / 1 ps
+
+`include "caravel.v"
+`include "spiflash.v"
+
+module timer_tb;
+ wire VDD3V3;
+ assign VDD3V3 = 1'b1;
+
+ reg clock;
+
+ always #10 clock <= (clock === 1'b0);
+
+ initial begin
+ clock <= 0;
+ end
+
+ initial begin
+ $dumpfile("timer.vcd");
+ $dumpvars(0, timer_tb);
+
+ // Repeat cycles of 1000 clock edges as needed to complete testbench
+ repeat (25) begin
+ repeat (1000) @(posedge clock);
+ $display("+1000 cycles");
+ end
+ $display("%c[1;31m",27);
+ $display ("Monitor: Timeout, Test GPIO (RTL) Failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ wire [36:0] mprj_io; // Most of these are no-connects
+ wire [15:0] checkbits;
+ reg [7:0] checkbits_lo;
+ wire [7:0] checkbits_hi;
+
+ assign mprj_io[23:16] = checkbits_lo;
+ assign checkbits = mprj_io[31:16];
+ assign checkbits_hi = checkbits[15:8];
+
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+
+ reg RSTB;
+
+ // Transactor
+ initial begin
+ checkbits_lo <= {8{1'bz}};
+ wait(checkbits_hi == 8'hA0);
+ checkbits_lo <= 8'hF0;
+ wait(checkbits_hi == 8'h0B);
+ checkbits_lo <= 8'h0F;
+ wait(checkbits_hi == 8'hAB);
+ checkbits_lo <= 8'h0;
+ repeat (1000) @(posedge clock);
+ checkbits_lo <= 8'h1;
+ repeat (1000) @(posedge clock);
+ checkbits_lo <= 8'h3;
+ end
+
+ // Monitor
+ initial begin
+ wait(checkbits_hi == 8'hA0);
+ wait(checkbits[7:0] == 8'hF0);
+ wait(checkbits_hi == 8'h0B);
+ wait(checkbits[7:0] == 8'h0F);
+ wait(checkbits_hi == 8'hAB);
+ wait(checkbits[7:0] == 8'h00);
+ wait(checkbits_hi == 8'h01);
+ wait(checkbits[7:0] == 8'h01);
+ wait(checkbits_hi == 8'h02);
+ wait(checkbits[7:0] == 8'h03);
+ wait(checkbits_hi == 8'h04);
+ $display("Monitor: Test GPIO (RTL) Passed");
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+
+ #1000;
+ RSTB <= 1'b1; // Release reset
+ #2000;
+ end
+
+ always @(checkbits) begin
+ #1 $display("GPIO state = %b (%d - %d)", checkbits,
+ checkbits_hi, checkbits_lo);
+ end
+
+ wire VDD1V8;
+ wire VSS;
+
+ assign VSS = 1'b0;
+ assign VDD1V8 = 1'b1;
+
+ // These are the mappings of mprj_io GPIO pads that are set to
+ // specific functions on startup:
+ //
+ // JTAG = mgmt_gpio_io[0] (inout)
+ // SDO = mgmt_gpio_io[1] (output)
+ // SDI = mgmt_gpio_io[2] (input)
+ // CSB = mgmt_gpio_io[3] (input)
+ // SCK = mgmt_gpio_io[4] (input)
+ // ser_rx = mgmt_gpio_io[5] (input)
+ // ser_tx = mgmt_gpio_io[6] (output)
+ // irq = mgmt_gpio_io[7] (input)
+
+ caravel uut (
+ .vddio (VDD3V3),
+ .vssio (VSS),
+ .vdda (VDD3V3),
+ .vssa (VSS),
+ .vccd (VDD1V8),
+ .vssd (VSS),
+ .vdda1 (VDD3V3),
+ .vdda2 (VDD3V3),
+ .vssa1 (VSS),
+ .vssa2 (VSS),
+ .vccd1 (VDD1V8),
+ .vccd2 (VDD1V8),
+ .vssd1 (VSS),
+ .vssd2 (VSS),
+ .clock (clock),
+ .gpio (gpio),
+ .mprj_io (mprj_io),
+ .flash_csb(flash_csb),
+ .flash_clk(flash_clk),
+ .flash_io0(flash_io0),
+ .flash_io1(flash_io1),
+ .resetb (RSTB)
+ );
+
+ spiflash #(
+ .FILENAME("timer.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+endmodule
diff --git a/verilog/rtl/housekeeping_spi.v b/verilog/rtl/housekeeping_spi.v
index 0a1cce6..c6a4860 100644
--- a/verilog/rtl/housekeeping_spi.v
+++ b/verilog/rtl/housekeeping_spi.v
@@ -271,7 +271,7 @@
// 01000000 Read until CSB raised
// 11000000 Simultaneous read/write until CSB raised
// 11000100 Pass-through read/write to management area flash SPI until CSB raised
-// 11000101 Pass-through read/write to user area flash SPI until CSB raised
+// 11000010 Pass-through read/write to user area flash SPI until CSB raised
// wrnnn000 Read/write as above, for nnn = 1 to 7 bytes, then terminate
// Lower three bits are reserved for future use.
@@ -414,10 +414,13 @@
readmode <= SDI;
end else if (count < 3'b101) begin
fixed <= {fixed[1:0], SDI};
- end else if (count < 3'b110) begin
+ end else if (count == 3'b101) begin
+ pre_pass_thru_mgmt <= SDI;
+ end else if (count == 3'b110) begin
+ pre_pass_thru_user <= SDI;
pass_thru_mgmt_delay <= pre_pass_thru_mgmt;
- pass_thru_user_delay <= pre_pass_thru_user;
end else if (count == 3'b111) begin
+ pass_thru_user_delay <= pre_pass_thru_user;
if (pre_pass_thru_mgmt == 1'b1) begin
state <= `MGMTPASS;
pre_pass_thru_mgmt <= 1'b0;
@@ -454,7 +457,11 @@
end else begin
rdstb <= 1'b0;
end
- end // ! state `DATA
+ end else if (state == `MGMTPASS) begin
+ pass_thru_mgmt <= 1'b1;
+ end else if (state == `USERPASS) begin
+ pass_thru_user <= 1'b1;
+ end // ! state `DATA | `MGMTPASS | `USERPASS
end // ! csb_reset
end // always @ SCK
diff --git a/verilog/rtl/spimemio.v b/verilog/rtl/spimemio.v
index 2d0b6fe..074fff7 100644
--- a/verilog/rtl/spimemio.v
+++ b/verilog/rtl/spimemio.v
@@ -318,7 +318,7 @@
assign flash_clk_ieb = 1'b1; /* Always disabled */
assign flash_io0_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io0_oe : config_oe[0]);
- assign flash_io1_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io1_oe : config_oe[1]);
+ assign flash_io1_ieb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : (config_en ? xfer_io1_oe : config_oe[1]);
assign flash_io2_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io2_oe : config_oe[2]);
assign flash_io3_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io3_oe : config_oe[3]);