Merge pull request #18 from Manarabdelaty/develop
Added GL simulations
diff --git a/verilog/dv/caravel/mgmt_soc/gpio_gl/Makefile b/verilog/dv/caravel/mgmt_soc/gpio_gl/Makefile
new file mode 100644
index 0000000..f896dc0
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/gpio_gl/Makefile
@@ -0,0 +1,44 @@
+FIRMWARE_PATH = ../..
+VERILOG_PATH = ../../../..
+RTL_PATH = $(VERILOG_PATH)/rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = gpio
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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/gpio_gl/README b/verilog/dv/caravel/mgmt_soc/gpio_gl/README
new file mode 100644
index 0000000..f1935dd
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/gpio_gl/README
@@ -0,0 +1,27 @@
+------------------------------------------------
+Caravel
+gpio testbench
+------------------------------------------------
+
+This testbench exercises the fundamental use of the Caravel
+management SoC to drive the I/O in the user area as general
+purpose I/O on startup.
+
+On startup, all GPIO are configured as input to the management
+region (so as to be high impedence to the external world) and
+decoupled from the user project area.
+
+To configure any GPIO as output, the appropriate memory-mapped
+location for the I/O must be properly configured. Since the
+I/O configuration is stored in two places, in the SoC, but
+also locally at each I/O pad, the "transfer" bit must be
+applied, which initiates a transfer of the configuration data
+around the padframe.
+
+The testbench takes 16 pins from the user area and checks
+functionality by applying input values on 8 of these pins from
+the testbench verilog, detecting them in the C program, then
+copying the values to the other 8 pins, and detecting those
+values in the testbench verilog.
+
+If any of that does not work, then the testbench will fail.
diff --git a/verilog/dv/caravel/mgmt_soc/gpio_gl/gpio.c b/verilog/dv/caravel/mgmt_soc/gpio_gl/gpio.c
new file mode 100644
index 0000000..1e1e48a
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/gpio_gl/gpio.c
@@ -0,0 +1,98 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+/*
+ * GPIO Test
+ * Tests PU and PD on the lower 8 pins while being driven from outside
+ * Tests Writing to the upper 8 pins
+ * Tests reading from the lower 8 pins
+ */
+
+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/gpio_gl/gpio_tb.v b/verilog/dv/caravel/mgmt_soc/gpio_gl/gpio_tb.v
new file mode 100644
index 0000000..49a3467
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/gpio_gl/gpio_tb.v
@@ -0,0 +1,185 @@
+`default_nettype none
+/*
+ * 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
+
+`define GL
+
+`include "caravel.v"
+`include "spiflash.v"
+
+module gpio_tb;
+
+ reg clock;
+ reg power1;
+ reg power2;
+
+ always #10 clock <= (clock === 1'b0);
+
+ initial begin
+ clock <= 0;
+ end
+
+ initial begin
+ $dumpfile("gpio.vcd");
+ $dumpvars(0, gpio_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 (GL) Failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ wire [37: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;
+ wire gpio;
+
+ 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 (GL) Passed");
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+
+ #1000;
+ RSTB <= 1'b1; // Release reset
+ #2000;
+ end
+
+ initial begin // Power-up
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ end
+
+
+ always @(checkbits) begin
+ #1 $display("GPIO state = %b (%d - %d)", checkbits,
+ checkbits_hi, checkbits_lo);
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+ assign VSS = 1'b0;
+
+ // 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("gpio.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/caravel/mgmt_soc/hkspi_gl/Makefile b/verilog/dv/caravel/mgmt_soc/hkspi_gl/Makefile
new file mode 100644
index 0000000..be47dd2
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/hkspi_gl/Makefile
@@ -0,0 +1,44 @@
+FIRMWARE_PATH = ../..
+VERILOG_PATH = ../../../..
+RTL_PATH = $(VERILOG_PATH)/rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = hkspi
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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/hkspi_gl/hkspi.c b/verilog/dv/caravel/mgmt_soc/hkspi_gl/hkspi.c
new file mode 100644
index 0000000..826bf59
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/hkspi_gl/hkspi.c
@@ -0,0 +1,75 @@
+#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 interrupted only when the reset is applied
+ // through the SPI.
+
+ // 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 message
+ print("\n");
+ print(" ____ _ ____ ____\n");
+ print(" | _ \\(_) ___ ___/ ___| ___ / ___|\n");
+ print(" | |_) | |/ __/ _ \\___ \\ / _ \\| |\n");
+ print(" | __/| | (_| (_) |__) | (_) | |___\n");
+ print(" |_| |_|\\___\\___/____/ \\___/ \\____|\n");
+
+ reg_mprj_datal = 0xab000000;
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/hkspi_gl/hkspi_tb.v b/verilog/dv/caravel/mgmt_soc/hkspi_gl/hkspi_tb.v
new file mode 100644
index 0000000..88b8edf
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/hkspi_gl/hkspi_tb.v
@@ -0,0 +1,298 @@
+`default_nettype none
+/*
+ StriVe housekeeping SPI testbench.
+*/
+`define GL
+
+`timescale 1 ns / 1 ps
+
+`include "caravel.v"
+`include "spiflash.v"
+`include "tbuart.v"
+
+module hkspi_tb;
+ reg clock;
+ reg SDI, CSB, SCK, RSTB;
+ reg power1, power2;
+
+ wire gpio;
+ wire [15:0] checkbits;
+ wire [37: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
+
+ initial begin // Power-up sequence
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ 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("hkspi.vcd");
+ $dumpvars(0, hkspi_tb);
+
+ CSB <= 1'b1;
+ SCK <= 1'b0;
+ SDI <= 1'b0;
+ RSTB <= 1'b0;
+
+ // Delay, then bring chip out of reset
+ #1000;
+ RSTB <= 1'b1;
+ #2000;
+
+ // 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);
+
+ // Toggle external reset
+ start_csb();
+ write_byte(8'h80); // Write stream command
+ write_byte(8'h07); // Address (register 7 = external reset)
+ write_byte(8'h01); // Data = 0x01 (apply external reset)
+ end_csb();
+
+ start_csb();
+ write_byte(8'h80); // Write stream command
+ write_byte(8'h07); // Address (register 7 = external reset)
+ write_byte(8'h00); // Data = 0x00 (release external reset)
+ end_csb();
+
+ // Read all registers (0 to 18)
+ start_csb();
+ write_byte(8'h40); // Read stream command
+ write_byte(8'h00); // Address (register 3 = product ID)
+ read_byte(tbdata);
+
+ $display("Read register 0 = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 1 = 0x%02x (should be 0x04)", tbdata);
+ if(tbdata !== 8'h04) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 2 = 0x%02x (should be 0x56)", tbdata);
+ if(tbdata !== 8'h56) begin $display("Monitor: Test HK SPI (RTL) Failed, %02x", tbdata); $finish; end
+ read_byte(tbdata);
+ $display("Read register 3 = 0x%02x (should be 0x10)", tbdata);
+ if(tbdata !== 8'h10) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 4 = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 5 = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 6 = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 7 = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 8 = 0x%02x (should be 0x02)", tbdata);
+ if(tbdata !== 8'h02) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 9 = 0x%02x (should be 0x01)", tbdata);
+ if(tbdata !== 8'h01) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 10 = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 11 = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 12 = 0x%02x (should be 0x00)", tbdata);
+ if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 13 = 0x%02x (should be 0xff)", tbdata);
+ if(tbdata !== 8'hff) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 14 = 0x%02x (should be 0xef)", tbdata);
+ if(tbdata !== 8'hef) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 15 = 0x%02x (should be 0xff)", tbdata);
+ if(tbdata !== 8'hff) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 16 = 0x%02x (should be 0x03)", tbdata);
+ if(tbdata !== 8'h03) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 17 = 0x%02x (should be 0x12)", tbdata);
+ if(tbdata !== 8'h12) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+ read_byte(tbdata);
+ $display("Read register 18 = 0x%02x (should be 0x04)", tbdata);
+ if(tbdata !== 8'h04) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+
+ end_csb();
+
+ $display("Monitor: Test HK SPI (GL) Passed");
+
+ #10000;
+ $finish;
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+ assign VSS = 1'b0;
+
+ 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("hkspi.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
+`default_nettype wire
diff --git a/verilog/dv/caravel/mgmt_soc/mem_gl/Makefile b/verilog/dv/caravel/mgmt_soc/mem_gl/Makefile
new file mode 100644
index 0000000..16e340e
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/mem_gl/Makefile
@@ -0,0 +1,44 @@
+FIRMWARE_PATH = ../..
+VERILOG_PATH = ../../../..
+RTL_PATH = $(VERILOG_PATH)/rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = mem
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -DUSE_POWER_PINS -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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/mem_gl/mem.c b/verilog/dv/caravel/mgmt_soc/mem_gl/mem.c
new file mode 100644
index 0000000..7fbf8ad
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/mem_gl/mem.c
@@ -0,0 +1,76 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+/*
+ Memory Test
+ It uses GPIO to flag the success or failure of the test
+*/
+unsigned int ints[10];
+unsigned short shorts[10];
+unsigned char bytes[10];
+
+void main()
+{
+ int i;
+
+ /* Upper 16 user area pins are configured to be GPIO 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;
+
+ // Apply configuration
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ // start test
+ reg_mprj_datal = 0xA0400000;
+
+ // Test Word R/W
+ for (i=0; i<10; i++)
+ ints[i] = i*5000 + 10000;
+
+ for (i=0; i<10; i++)
+ if ((i*5000+10000) != ints[i])
+ reg_mprj_datal = 0xAB400000;
+
+ reg_mprj_datal = 0xAB410000;
+
+ // Test Half Word R/W
+ reg_mprj_datal = 0xA0200000;
+ for (i=0; i<10; i++)
+ shorts[i] = i*500 + 100;
+
+ for(i=0; i<10; i++)
+ if((i*500+100) != shorts[i])
+ reg_mprj_datal = 0xAB200000;
+
+ reg_mprj_datal = 0xAB210000;
+
+ // Test byte R/W
+ reg_mprj_datal = 0xA0100000;
+ for(i=0; i<10; i++)
+ bytes[i] = i*5 + 10;
+
+ for(i=0; i<10; i++)
+ if((i*5+10) != bytes[i])
+ reg_mprj_datal = 0xAB100000;
+
+ reg_mprj_datal = 0xAB110000;
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/mem_gl/mem_tb.v b/verilog/dv/caravel/mgmt_soc/mem_gl/mem_tb.v
new file mode 100644
index 0000000..c633468
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/mem_gl/mem_tb.v
@@ -0,0 +1,171 @@
+`default_nettype none
+/*
+ * 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
+
+`define GL
+
+`include "caravel.v"
+`include "spiflash.v"
+
+module mem_tb;
+ reg clock;
+ reg RSTB;
+ reg power1, power2;
+
+ wire gpio;
+ wire [15:0] checkbits;
+ wire [37:0] mprj_io;
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+
+ assign checkbits = mprj_io[31:16];
+
+ // 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 #10 clock <= (clock === 1'b0);
+
+ initial begin
+ clock = 0;
+ end
+
+ initial begin
+ $dumpfile("mem.vcd");
+ $dumpvars(0, mem_tb);
+
+ // Repeat cycles of 1000 clock edges as needed to complete testbench
+ repeat (100) begin
+ repeat (1000) @(posedge clock);
+ //$display("+1000 cycles");
+ end
+ $display("%c[1;31m",27);
+ $display ("Monitor: Timeout, Test MEM (GL) Failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+ #1000;
+ RSTB <= 1'b1; // Release reset
+ #2000;
+ end
+
+ initial begin // Power-up sequence
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ end
+
+ always @(checkbits) begin
+ if(checkbits == 16'hA040) begin
+ $display("Mem Test (word rw) started");
+ end
+ else if(checkbits == 16'hAB40) begin
+ $display("%c[1;31m",27);
+ $display("Monitor: Test MEM (GL) [word rw] failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+ else if(checkbits == 16'hAB41) begin
+ $display("Monitor: Test MEM (GL) [word rw] passed");
+ end
+ else if(checkbits == 16'hA020) begin
+ $display("Mem Test (short rw) started");
+ end
+ else if(checkbits == 16'hAB20) begin
+ $display("%c[1;31m",27);
+ $display("Monitor: Test MEM (GL) [short rw] failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+ else if(checkbits == 16'hAB21) begin
+ $display("Monitor: Test MEM (GL) [short rw] passed");
+ end
+ else if(checkbits == 16'hA010) begin
+ $display("Mem Test (byte rw) started");
+ end
+ else if(checkbits == 16'hAB10) begin
+ $display("%c[1;31m",27);
+ $display("Monitor: Test MEM (GL) [byte rw] failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+ else if(checkbits == 16'hAB11) begin
+ $display("Monitor: Test MEM (GL) [byte rw] passed");
+ $finish;
+ end
+
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VSS = 1'b0;
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+
+ 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("mem.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/caravel/mgmt_soc/mprj_ctrl_gl/Makefile b/verilog/dv/caravel/mgmt_soc/mprj_ctrl_gl/Makefile
new file mode 100644
index 0000000..b1d5ec9
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/mprj_ctrl_gl/Makefile
@@ -0,0 +1,44 @@
+FIRMWARE_PATH = ../..
+VERILOG_PATH = ../../../..
+RTL_PATH = $(VERILOG_PATH)/rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = mprj_ctrl
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -DUSE_POWER_PINS -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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/mprj_ctrl_gl/mprj_ctrl.c b/verilog/dv/caravel/mgmt_soc/mprj_ctrl_gl/mprj_ctrl.c
new file mode 100644
index 0000000..75b41d4
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/mprj_ctrl_gl/mprj_ctrl.c
@@ -0,0 +1,91 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+/*
+ * User Project IO Control Test
+ */
+
+void main()
+{
+ /* All GPIO pins are configured to be output */
+ /* The lower 28 bits are connected to the user */
+ /* project to output the counter result, and the */
+ /* upper 4 bits are connected to the management */
+ /* SoC to apply values that can be flagged by the */
+ /* testbench for specific benchmark tests. */
+
+ /* GPIOs 31 to 16 are connected to the management SoC */
+ 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;
+
+ /* GPIOs 27 to 0 are connected to the user area */
+ reg_mprj_io_27 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_26 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_25 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_24 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_23 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_22 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_21 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_20 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_19 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_18 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_17 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_16 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_15 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_14 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_13 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_12 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_11 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_10 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_9 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_8 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_7 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_6 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_5 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_4 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_3 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_2 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_1 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_0 = GPIO_MODE_USER_STD_OUTPUT;
+
+ // Apply configuration
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ reg_mprj_datal = 0;
+
+ // start test
+ reg_mprj_datal = 0x50000000;
+
+ // Write to IO Control
+ reg_mprj_io_0 = 0x004F;
+ if (reg_mprj_io_0 != 0x004F)
+ reg_mprj_datal = 0x60000000;
+ else
+ reg_mprj_datal = 0x70000000;
+
+ // Write to IO Control
+ reg_mprj_io_1 = 0x005F;
+ if (reg_mprj_io_1 != 0x005F)
+ reg_mprj_datal = 0x80000000;
+ else
+ reg_mprj_datal = 0x90000000;
+
+ // Write to IO Control
+ reg_mprj_io_2 = 0x006F;
+ if (reg_mprj_io_2 != 0x006F)
+ reg_mprj_datal = 0xA0000000;
+ else
+ reg_mprj_datal = 0xb0000000;
+
+ // Write to IO Control (NOTE: Only 13 bits are valid)
+ reg_mprj_io_3 = 0xF0F5;
+ if (reg_mprj_io_3 != 0x10F5)
+ reg_mprj_datal = 0xc0000000;
+ else
+ reg_mprj_datal = 0xd0000000;
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/mprj_ctrl_gl/mprj_ctrl_tb.v b/verilog/dv/caravel/mgmt_soc/mprj_ctrl_gl/mprj_ctrl_tb.v
new file mode 100644
index 0000000..a907b55
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/mprj_ctrl_gl/mprj_ctrl_tb.v
@@ -0,0 +1,151 @@
+`default_nettype none
+
+`timescale 1 ns / 1 ps
+
+`define GL
+
+`include "caravel.v"
+`include "spiflash.v"
+
+module mprj_ctrl_tb;
+ reg clock;
+ reg RSTB;
+ reg power1, power2;
+
+ wire gpio;
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+ wire [37:0] user_io;
+ wire SDO;
+
+ wire [3:0] checkbits;
+
+ assign checkbits = user_io[31:28];
+
+ // 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 #10 clock <= (clock === 1'b0);
+
+ initial begin
+ clock = 0;
+ end
+
+ initial begin
+ $dumpfile("mprj_ctrl.vcd");
+ $dumpvars(0, mprj_ctrl_tb);
+ repeat (25) begin
+ repeat (1000) @(posedge clock);
+ $display("+1000 cycles");
+ end
+ $display("%c[1;31m",27);
+ $display ("Monitor: Timeout, Test User Project (GL) Failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ always @(checkbits) begin
+ if(checkbits == 4'h5) begin
+ $display("User Project control Test started");
+ end else if(checkbits == 4'h6) begin
+ $display("%c[1;31m",27);
+ $display("Monitor: IO control R/W failed (check 6)");
+ $display("%c[0m",27);
+ $finish;
+ end else if(checkbits == 4'h7) begin
+ $display("Monitor: IO control R/W passed (check 7)");
+ end else if(checkbits == 4'h8) begin
+ $display("%c[1;31m",27);
+ $display("Monitor: power control R/W failed (check 8)");
+ $display("%c[0m",27);
+ $finish;
+ end else if(checkbits == 4'h9) begin
+ $display("Monitor: power control R/W passed (check 9)");
+ end else if(checkbits == 4'ha) begin
+ $display("%c[1;31m",27);
+ $display("Monitor: power control R/W failed (check 10)");
+ $display("%c[0m",27);
+ $finish;
+ end else if(checkbits == 4'hb) begin
+ $display("Monitor: power control R/W passed (check 11)");
+ end else if(checkbits == 4'hc) begin
+ $display("%c[1;31m",27);
+ $display("Monitor: power control R/W failed (check 12)");
+ $display("%c[0m",27);
+ $finish;
+ end else if(checkbits == 4'hd) begin
+ $display("Monitor: power control R/W passed (check 13)");
+ $display("Monitor: User Project control (GL) test passed.");
+ $finish;
+ end
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+ #1000;
+ RSTB <= 1'b1; // Release reset
+ #2000;
+ end
+
+ initial begin
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ end
+
+ always @(gpio) begin
+ #1 $display("GPIO state = %b ", gpio);
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+ assign VSS = 1'b0;
+
+ 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 (user_io),
+ .flash_csb (flash_csb),
+ .flash_clk (flash_clk),
+ .flash_io0 (flash_io0),
+ .flash_io1 (flash_io1),
+ .resetb (RSTB)
+ );
+
+ spiflash #(
+ .FILENAME("mprj_ctrl.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/caravel/mgmt_soc/pass_thru_gl/Makefile b/verilog/dv/caravel/mgmt_soc/pass_thru_gl/Makefile
new file mode 100644
index 0000000..f043a9a
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pass_thru_gl/Makefile
@@ -0,0 +1,44 @@
+FIRMWARE_PATH = ../..
+VERILOG_PATH = ../../../..
+RTL_PATH = $(VERILOG_PATH)/rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = pass_thru
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -DUSE_POWER_PINS -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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_gl/pass_thru.c b/verilog/dv/caravel/mgmt_soc/pass_thru_gl/pass_thru.c
new file mode 100644
index 0000000..d31b31f
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pass_thru_gl/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_gl/pass_thru_tb.v b/verilog/dv/caravel/mgmt_soc/pass_thru_gl/pass_thru_tb.v
new file mode 100644
index 0000000..e2587ee
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pass_thru_gl/pass_thru_tb.v
@@ -0,0 +1,272 @@
+`default_nettype none
+/*
+ * StriVe housekeeping pass-thru mode SPI testbench.
+ */
+
+`timescale 1 ns / 1 ps
+
+`define GL
+
+`include "caravel.v"
+`include "spiflash.v"
+`include "tbuart.v"
+
+module pass_thru_tb;
+ reg clock;
+ reg SDI, CSB, SCK, RSTB;
+ reg power1, power2;
+
+ wire gpio;
+ wire [15:0] checkbits;
+ wire [37: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
+
+ initial begin // Power-up sequence
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ 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 (GL) 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 (GL) 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 (GL) 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 (GL) 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 (GL) 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 (GL) 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 (GL) 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 (GL) 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 (GL) 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 (GL) Failed"); $finish; end
+
+ $display("Monitor: Test HK SPI Pass-thru (GL) Passed");
+
+ #10000;
+ $finish;
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+ assign VSS = 1'b0;
+
+ 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
+`default_nettype wire
diff --git a/verilog/dv/caravel/mgmt_soc/perf_gl/Makefile b/verilog/dv/caravel/mgmt_soc/perf_gl/Makefile
new file mode 100644
index 0000000..f5e0730
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/perf_gl/Makefile
@@ -0,0 +1,44 @@
+FIRMWARE_PATH = ../..
+VERILOG_PATH = ../../../..
+RTL_PATH = $(VERILOG_PATH)/rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = perf
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -DUSE_POWER_PINS -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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/perf_gl/perf.c b/verilog/dv/caravel/mgmt_soc/perf_gl/perf.c
new file mode 100644
index 0000000..0d83518
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/perf_gl/perf.c
@@ -0,0 +1,54 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+/*
+ Performance Test
+ It uses GPIO to flag the success or failure of the test
+*/
+unsigned int ints[50];
+unsigned short shorts[50];
+unsigned char bytes[50];
+
+int main()
+{
+ int i;
+ int sum = 0;
+
+ /* Upper 16 user area pins are configured to be GPIO 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;
+
+ // Apply configuration
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ reg_mprj_datal = 0;
+
+ // start test
+ reg_mprj_datal = 0xA0000000;
+
+ for (i=0; i<100; i++)
+ sum += (sum + i);
+
+ reg_mprj_datal = 0xAB000000;
+
+ return sum;
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/perf_gl/perf_tb.v b/verilog/dv/caravel/mgmt_soc/perf_gl/perf_tb.v
new file mode 100644
index 0000000..be9410a
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/perf_gl/perf_tb.v
@@ -0,0 +1,147 @@
+`default_nettype none
+/*
+ * 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
+
+`define GL
+
+`include "caravel.v"
+`include "spiflash.v"
+
+module perf_tb;
+ reg clock;
+ reg RSTB;
+ reg power1, power2;
+
+ wire gpio;
+ wire [15:0] checkbits;
+ wire [37:0] mprj_io;
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+
+ assign checkbits = mprj_io[31:16];
+
+ // 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 #10 clock <= (clock === 1'b0);
+
+ initial begin
+ clock = 0;
+ end
+
+ reg [31:0] kcycles;
+
+ initial begin
+ $dumpfile("perf.vcd");
+ $dumpvars(0, perf_tb);
+
+ kcycles = 0;
+ // Repeat cycles of 1000 clock edges as needed to complete testbench
+ repeat (150) begin
+ repeat (1000) @(posedge clock);
+ //$display("+1000 cycles");
+ kcycles <= kcycles + 1;
+ end
+ $display("%c[1;31m",27);
+ $display ("Monitor: Timeout, Test Performance (GL) Failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+ #1000;
+ RSTB <= 1'b1; // Release reset
+ #2000;
+ end
+
+ initial begin // Power-up sequence
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ end
+
+ always @(checkbits) begin
+ //#1 $display("GPIO state = %X ", gpio);
+ if(checkbits == 16'hA000) begin
+ kcycles = 0;
+ $display("Performance Test started");
+ end
+ else if(checkbits == 16'hAB00) begin
+ //$display("Monitor: number of cycles/100 iterations: %d KCycles", kcycles);
+ $display("Monitor: Test Performance (GL) passed [%0d KCycles]", kcycles);
+ $finish;
+ end
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+ assign VSS = 1'b0;
+
+ 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("perf.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/caravel/mgmt_soc/pll_gl/Makefile b/verilog/dv/caravel/mgmt_soc/pll_gl/Makefile
new file mode 100644
index 0000000..da4e1c4
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pll_gl/Makefile
@@ -0,0 +1,44 @@
+FIRMWARE_PATH = ../..
+VERILOG_PATH = ../../../..
+RTL_PATH = $(VERILOG_PATH)/rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = pll
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -DUSE_POWER_PINS -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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/pll_gl/pll.c b/verilog/dv/caravel/mgmt_soc/pll_gl/pll.c
new file mode 100644
index 0000000..b74860b
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pll_gl/pll.c
@@ -0,0 +1,105 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+/*
+ * PLL Test (self-switching)
+ * - Enables SPI master
+ * - Uses SPI master to internally access the housekeeping SPI
+ * - Switches PLL bypass
+ * - Changes PLL divider
+ *
+ * Tesbench mostly copied from sysctrl
+ */
+void main()
+{
+ int i;
+
+ reg_mprj_datal = 0;
+
+ // Configure upper 16 bits of user GPIO for generating testbench
+ // checkpoints.
+
+ 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;
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ // Start test
+ reg_mprj_datal = 0xA0400000;
+
+ // Enable SPI master
+ // SPI master configuration bits:
+ // bits 7-0: Clock prescaler value (default 2)
+ // bit 8: MSB/LSB first (0 = MSB first, 1 = LSB first)
+ // bit 9: CSB sense (0 = inverted, 1 = noninverted)
+ // bit 10: SCK sense (0 = noninverted, 1 = inverted)
+ // bit 11: mode (0 = read/write opposite edges, 1 = same edges)
+ // bit 12: stream (1 = CSB ends transmission)
+ // bit 13: enable (1 = enabled)
+ // bit 14: IRQ enable (1 = enabled)
+ // bit 15: Connect to housekeeping SPI (1 = connected)
+
+ reg_spimaster_config = 0xa002; // Enable, prescaler = 2,
+ // connect to housekeeping SPI
+
+ // Apply stream read (0x40 + 0x03) and read back one byte
+
+ reg_spimaster_config = 0xb002; // Apply stream mode
+ reg_spimaster_data = 0x80; // Write 0x80 (write mode)
+ reg_spimaster_data = 0x08; // Write 0x18 (start address)
+ reg_spimaster_data = 0x01; // Write 0x01 to PLL enable, no DCO mode
+ reg_spimaster_config = 0xa102; // Release CSB (ends stream mode)
+
+ reg_spimaster_config = 0xb002; // Apply stream mode
+ reg_spimaster_data = 0x80; // Write 0x80 (write mode)
+ reg_spimaster_data = 0x11; // Write 0x11 (start address)
+ reg_spimaster_data = 0x03; // Write 0x03 to PLL output divider
+ reg_spimaster_config = 0xa102; // Release CSB (ends stream mode)
+
+ reg_spimaster_config = 0xb002; // Apply stream mode
+ reg_spimaster_data = 0x80; // Write 0x80 (write mode)
+ reg_spimaster_data = 0x09; // Write 0x09 (start address)
+ reg_spimaster_data = 0x00; // Write 0x00 to clock from PLL (no bypass)
+ reg_spimaster_config = 0xa102; // Release CSB (ends stream mode)
+
+ // Write checkpoint
+ reg_mprj_datal = 0xA0410000;
+
+ reg_spimaster_config = 0xb002; // Apply stream mode
+ reg_spimaster_data = 0x80; // Write 0x80 (write mode)
+ reg_spimaster_data = 0x12; // Write 0x12 (start address)
+ reg_spimaster_data = 0x03; // Write 0x03 to feedback divider (was 0x04)
+ reg_spimaster_config = 0xa102; // Release CSB (ends stream mode)
+
+ // Write checkpoint
+ reg_mprj_datal = 0xA0420000;
+
+ reg_spimaster_config = 0xb002; // Apply stream mode
+ reg_spimaster_data = 0x80; // Write 0x80 (write mode)
+ reg_spimaster_data = 0x11; // Write 0x11 (start address)
+ reg_spimaster_data = 0x04; // Write 0x04 to PLL output divider
+ reg_spimaster_config = 0xa102; // Release CSB (ends stream mode)
+
+ reg_spimaster_config = 0x2102; // Release housekeeping SPI
+
+ // End test
+ reg_mprj_datal = 0xA0900000;
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/pll_gl/pll_tb.v b/verilog/dv/caravel/mgmt_soc/pll_gl/pll_tb.v
new file mode 100644
index 0000000..149517a
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pll_gl/pll_tb.v
@@ -0,0 +1,140 @@
+`default_nettype none
+
+`timescale 1 ns / 1 ps
+
+`define GL
+
+`include "caravel.v"
+`include "spiflash.v"
+
+module pll_tb;
+ reg clock;
+ reg power1;
+ reg power2;
+ reg RSTB;
+
+ wire gpio;
+ wire [15:0] checkbits;
+ wire [7:0] spivalue;
+ wire [37:0] mprj_io;
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+ wire SDO;
+
+ assign checkbits = mprj_io[31:16];
+ assign spivalue = mprj_io[15:8];
+
+ // 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 #10 clock <= (clock === 1'b0);
+
+ initial begin
+ clock = 0;
+ end
+
+ initial begin
+ $dumpfile("pll.vcd");
+ $dumpvars(0, pll_tb);
+ repeat (25) begin
+ repeat (1000) @(posedge clock);
+ $display("+1000 cycles");
+ end
+ $display("%c[1;31m",27);
+ $display ("Monitor: Timeout, Test PLL (GL) Failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ // Monitor
+ initial begin
+ wait(checkbits == 16'hA040);
+ $display("Monitor: Test PLL (GL) Started");
+
+ wait(checkbits == 16'hA041);
+ // $display(" SPI value = 0x%x (should be 0x04)", spivalue);
+ // if(spivalue !== 32'h04) begin
+ // $display("Monitor: Test PLL (GL) Failed");
+ // $finish;
+ // end
+ wait(checkbits == 16'hA042);
+ // $display(" SPI value = 0x%x (should be 0x56)", spivalue);
+ // if(spivalue !== 32'h56) begin
+ // $display("Monitor: Test PLL (GL) Failed");
+ // $finish;
+ // end
+
+ wait(checkbits == 16'hA090);
+ $display("Monitor: Test PLL (GL) Passed");
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+ #1000;
+ RSTB <= 1'b1; // Release reset
+ #2000;
+ end
+
+ initial begin
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ end
+
+ always @(checkbits) begin
+ #1 $display("GPIO state = %b ", checkbits);
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+ assign VSS = 1'b0;
+
+ 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("pll.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/caravel/mgmt_soc/storage_gl/Makefile b/verilog/dv/caravel/mgmt_soc/storage_gl/Makefile
new file mode 100644
index 0000000..f1b3248
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/storage_gl/Makefile
@@ -0,0 +1,44 @@
+FIRMWARE_PATH = ../..
+VERILOG_PATH = ../../../..
+RTL_PATH = $(VERILOG_PATH)/rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = storage
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -DUSE_POWER_PINS -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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/storage_gl/storage.c b/verilog/dv/caravel/mgmt_soc/storage_gl/storage.c
new file mode 100644
index 0000000..b5f7408
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/storage_gl/storage.c
@@ -0,0 +1,70 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+/*
+ Storage area Test
+ It uses GPIO to flag the success or failure of the test
+*/
+
+void main()
+{
+ int i;
+ volatile uint32_t* ram_addr;
+ /* Upper 16 user area pins are configured to be GPIO 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;
+
+ // Apply configuration
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ // start test
+ reg_mprj_datal = 0xA0400000;
+
+ // Test Management R/W block0
+ for (i=0; i<10; i++){
+ ram_addr = ®_rw_block0 + i;
+ *ram_addr = i*5000 + 10000;
+ }
+
+ for (i=0; i<10; i++){
+ ram_addr = ®_rw_block0 + i;
+ if ((i*5000+10000) != *ram_addr)
+ reg_mprj_datal = 0xAB400000;
+ }
+
+ reg_mprj_datal = 0xAB410000;
+
+ // Test Management R/W block1
+ reg_mprj_datal = 0xA0200000;
+ for (i=0; i<10; i++){
+ ram_addr = ®_rw_block1 + i;
+ *ram_addr = i*5000 + 10000;
+ }
+
+ for (i=0; i<10; i++){
+ ram_addr = ®_rw_block1 + i;
+ if ((i*5000+10000) != *ram_addr)
+ reg_mprj_datal = 0xAB200000;
+ }
+
+ reg_mprj_datal = 0xAB210000;
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/storage_gl/storage_tb.v b/verilog/dv/caravel/mgmt_soc/storage_gl/storage_tb.v
new file mode 100644
index 0000000..ae1209a
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/storage_gl/storage_tb.v
@@ -0,0 +1,158 @@
+`default_nettype none
+/*
+ * 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
+
+`define GL
+
+`include "caravel.v"
+`include "spiflash.v"
+
+module storage_tb;
+ reg clock;
+ reg RSTB;
+ reg power1, power2;
+
+ wire gpio;
+ wire [15:0] checkbits;
+ wire [37:0] mprj_io;
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+
+ assign checkbits = mprj_io[31:16];
+
+ // 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 #10 clock <= (clock === 1'b0);
+
+ initial begin
+ clock = 0;
+ end
+
+ initial begin
+ $dumpfile("storage.vcd");
+ $dumpvars(0, storage_tb);
+
+ // Repeat cycles of 1000 clock edges as needed to complete testbench
+ repeat (100) begin
+ repeat (1000) @(posedge clock);
+ //$display("+1000 cycles");
+ end
+ $display("%c[1;31m",27);
+ $display ("Monitor: Timeout, Test Storage (GL) Failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+ #1000;
+ RSTB <= 1'b1; // Release reset
+ #2000;
+ end
+
+ initial begin // Power-up sequence
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ end
+
+ always @(checkbits) begin
+ if(checkbits == 16'hA040) begin
+ $display("Mem Test storage MGMT block0 (GL) [word rw] started");
+ end
+ else if(checkbits == 16'hAB40) begin
+ $display("%c[1;31m",27);
+ $display("Monitor: Test storage MGMT block0 (GL) [word rw] failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+ else if(checkbits == 16'hAB41) begin
+ $display("Monitor: Test storage MGMT block0 (GL) [word rw] passed");
+ end
+ else if(checkbits == 16'hA020) begin
+ $display("Mem Test storage MGMT block1 (GL) [word rw] started");
+ end
+ else if(checkbits == 16'hAB20) begin
+ $display("%c[1;31m",27);
+ $display("Monitor: Test storage MGMT block1 (GL) [word rw] failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+ else if(checkbits == 16'hAB21) begin
+ $display("Monitor: Test storage MGMT block1 (GL) [word rw] passed");
+ $finish;
+ end
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VSS = 1'b0;
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+
+ 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("storage.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/caravel/mgmt_soc/sysctrl_gl/Makefile b/verilog/dv/caravel/mgmt_soc/sysctrl_gl/Makefile
new file mode 100644
index 0000000..0cd4654
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/sysctrl_gl/Makefile
@@ -0,0 +1,43 @@
+FIRMWARE_PATH = ../..
+RTL_PATH = ../../../../rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = sysctrl
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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/sysctrl_gl/sysctrl.c b/verilog/dv/caravel/mgmt_soc/sysctrl_gl/sysctrl.c
new file mode 100644
index 0000000..3d2cefd
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/sysctrl_gl/sysctrl.c
@@ -0,0 +1,148 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+/*
+ * System Control Test
+ * - Enables SPI master
+ * - Uses SPI master to internally access the housekeeping SPI
+ * - Reads default value of SPI-Controlled registers
+ * - Flags failure/success using mprj_io
+ */
+void main()
+{
+ int i;
+ uint32_t value;
+
+ reg_mprj_datal = 0;
+
+ // Configure upper 16 bits of user GPIO for generating testbench
+ // checkpoints.
+
+ 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;
+
+ // Configure next 8 bits for writing the SPI value read on GPIO
+ reg_mprj_io_15 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_14 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_13 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_12 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_11 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_10 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_9 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_8 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ // Start test
+ reg_mprj_datal = 0xA0400000;
+
+ // Enable SPI master
+ // SPI master configuration bits:
+ // bits 7-0: Clock prescaler value (default 2)
+ // bit 8: MSB/LSB first (0 = MSB first, 1 = LSB first)
+ // bit 9: CSB sense (0 = inverted, 1 = noninverted)
+ // bit 10: SCK sense (0 = noninverted, 1 = inverted)
+ // bit 11: mode (0 = read/write opposite edges, 1 = same edges)
+ // bit 12: stream (1 = CSB ends transmission)
+ // bit 13: enable (1 = enabled)
+ // bit 14: IRQ enable (1 = enabled)
+ // bit 15: Connect to housekeeping SPI (1 = connected)
+
+ reg_spimaster_config = 0xa002; // Enable, prescaler = 2,
+ // connect to housekeeping SPI
+
+ // Apply stream read (0x40 + 0x03) and read back one byte
+
+ reg_spimaster_config = 0xb002; // Apply stream mode
+ reg_spimaster_data = 0x40; // Write 0x40 (read mode)
+ reg_spimaster_data = 0x01; // Write 0x01 (start address)
+
+ reg_spimaster_data = 0x00; // Write 0x00 for read
+ value = reg_spimaster_data; // Read back byte
+ // Write checkpoint
+ reg_mprj_datal = 0xA0410000 | (value << 8); // Mfgr ID (high)
+
+ reg_spimaster_data = 0x00; // Write 0x00 for read
+ value = reg_spimaster_data; // Read back byte
+ // Write checkpoint
+ reg_mprj_datal = 0xA0420000 | (value << 8); // Mfgr ID (low)
+
+ reg_spimaster_data = 0x00; // Write 0x00 for read
+ value = reg_spimaster_data; // Read back byte
+ // Write checkpoint
+ reg_mprj_datal = 0xA0430000 | (value << 8); // Prod ID
+
+ reg_spimaster_config = 0xa102; // Release CSB (ends stream mode)
+ reg_spimaster_config = 0xb002; // Apply stream mode
+ reg_spimaster_data = 0x40; // Write 0x40 (read mode)
+ reg_spimaster_data = 0x08; // Write 0x08 (start address)
+
+ reg_spimaster_data = 0x00; // Write 0x00 for read
+ value = reg_spimaster_data; // Read back byte
+ // Write checkpoint
+ reg_mprj_datal = 0xA0440000 | (value << 8); // PLL enable
+
+ reg_spimaster_data = 0x00; // Write 0x00 for read
+ value = reg_spimaster_data; // Read back byte
+ // Write checkpoint
+ reg_mprj_datal = 0xA0450000 | (value << 8); // PLL bypass
+
+ reg_spimaster_config = 0xa102; // Release CSB (ends stream mode)
+ reg_spimaster_config = 0xb002; // Apply stream mode
+ reg_spimaster_data = 0x40; // Write 0x40 (read mode)
+ reg_spimaster_data = 0x0d; // Write 0x0d (start address)
+
+ reg_spimaster_data = 0x00; // Write 0x00 for read
+ value = reg_spimaster_data; // Read back byte
+ // Write checkpoint
+ reg_mprj_datal = 0xA0460000 | (value << 8); // PLL trim (2 high bits)
+
+ reg_spimaster_data = 0x00; // Write 0x00 for read
+ value = reg_spimaster_data; // Read back byte
+ // Write checkpoint
+ reg_mprj_datal = 0xA0470000 | (value << 8); // PLL trim (2nd byte)
+
+ reg_spimaster_data = 0x00; // Write 0x00 for read
+ value = reg_spimaster_data; // Read back byte
+ // Write checkpoint
+ reg_mprj_datal = 0xA0480000 | (value << 8); // PLL trim (3rd byte)
+
+ reg_spimaster_data = 0x00; // Write 0x00 for read
+ value = reg_spimaster_data; // Read back byte
+ // Write checkpoint
+ reg_mprj_datal = 0xA0490000 | (value << 8); // PLL trim (low byte)
+
+ reg_spimaster_data = 0x00; // Write 0x00 for read
+ value = reg_spimaster_data; // Read back byte
+ // Write checkpoint
+ reg_mprj_datal = 0xA04a0000 | (value << 8); // PLL select (3 lowest bits)
+
+ reg_spimaster_data = 0x00; // Write 0x00 for read
+ value = reg_spimaster_data; // Read back byte
+ // Write checkpoint
+ reg_mprj_datal = 0xA04b0000 | (value << 8); // PLL divider (5 lowest bits)
+
+ reg_spimaster_config = 0xa102; // Release CSB (ends stream mode)
+ reg_spimaster_config = 0x2102; // Release housekeeping SPI
+
+ // End test
+ reg_mprj_datal = 0xA0900000;
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/sysctrl_gl/sysctrl_tb.v b/verilog/dv/caravel/mgmt_soc/sysctrl_gl/sysctrl_tb.v
new file mode 100644
index 0000000..8b33e6b
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/sysctrl_gl/sysctrl_tb.v
@@ -0,0 +1,193 @@
+`default_nettype none
+
+`timescale 1 ns / 1 ps
+
+`define GL
+
+`include "caravel.v"
+`include "spiflash.v"
+
+module sysctrl_tb;
+ reg clock;
+ reg RSTB;
+ reg power1, power2;
+
+ wire gpio;
+ wire [15:0] checkbits;
+ wire [7:0] spivalue;
+ wire [37:0] mprj_io;
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+ wire SDO;
+
+ assign checkbits = mprj_io[31:16];
+ assign spivalue = mprj_io[15:8];
+
+ // 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 #10 clock <= (clock === 1'b0);
+
+ initial begin
+ clock = 0;
+ end
+
+ initial begin
+ $dumpfile("sysctrl.vcd");
+ $dumpvars(0, sysctrl_tb);
+ repeat (25) begin
+ repeat (1000) @(posedge clock);
+ $display("+1000 cycles");
+ end
+ $display("%c[1;31m",27);
+ $display ("Monitor: Timeout, Test GPIO (GL) Failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ // Monitor
+ initial begin
+ wait(checkbits == 16'hA040);
+ $display("Monitor: Test Sysctrl (GL) Started");
+
+ wait(checkbits == 16'hA041);
+ $display(" SPI value = 0x%x (should be 0x04)", spivalue);
+ if(spivalue !== 32'h04) begin
+ $display("Monitor: Test Sysctrl (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 16'hA042);
+ $display(" SPI value = 0x%x (should be 0x56)", spivalue);
+ if(spivalue !== 32'h56) begin
+ $display("Monitor: Test Sysctrl (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 16'hA043);
+ $display(" SPI value = 0x%x (should be 0x10)", spivalue);
+ if(spivalue !== 32'h10) begin
+ $display("Monitor: Test Sysctrl (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 16'hA044);
+ $display(" SPI value = 0x%x (should be 0x02)", spivalue);
+ if(spivalue !== 32'h02) begin
+ $display("Monitor: Test Sysctrl (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 16'hA045);
+ $display(" SPI value = 0x%x (should be 0x01)", spivalue);
+ if(spivalue !== 32'h01) begin
+ $display("Monitor: Test Sysctrl (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 16'hA046);
+ $display(" SPI value = 0x%x (should be 0xff)", spivalue);
+ if(spivalue !== 32'hff) begin
+ $display("Monitor: Test Sysctrl (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 16'hA047);
+ $display(" SPI value = 0x%x (should be 0xef)", spivalue);
+ if(spivalue !== 32'hef) begin
+ $display("Monitor: Test Sysctrl (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 16'hA048);
+ $display(" SPI value = 0x%x (should be 0xff)", spivalue);
+ if(spivalue !== 32'hff) begin
+ $display("Monitor: Test Sysctrl (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 16'hA049);
+ $display(" SPI value = 0x%x (should be 0x03)", spivalue);
+ if(spivalue !== 32'h03) begin
+ $display("Monitor: Test Sysctrl (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 16'hA04a);
+ $display(" SPI value = 0x%x (should be 0x12)", spivalue);
+ if(spivalue !== 32'h12) begin
+ $display("Monitor: Test Sysctrl (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 16'hA04b);
+ $display(" SPI value = 0x%x (should be 0x04)", spivalue);
+ if(spivalue !== 32'h04) begin
+ $display("Monitor: Test Sysctrl (GL) Failed");
+ $finish;
+ end
+
+ wait(checkbits == 16'hA090);
+ $display("Monitor: Test Sysctrl (GL) Passed");
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+ #1000;
+ RSTB <= 1'b1; // Release reset
+ #2000;
+ end
+
+ initial begin // Power-up sequence
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ end
+
+ always @(checkbits) begin
+ #1 $display("GPIO state = %b ", checkbits);
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+ assign VSS = 1'b0;
+
+ 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("sysctrl.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/caravel/mgmt_soc/timer2_gl/Makefile b/verilog/dv/caravel/mgmt_soc/timer2_gl/Makefile
new file mode 100644
index 0000000..73cecf5
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer2_gl/Makefile
@@ -0,0 +1,43 @@
+FIRMWARE_PATH = ../..
+RTL_PATH = ../../../../rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = timer2
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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/timer2_gl/timer2.c b/verilog/dv/caravel/mgmt_soc/timer2_gl/timer2.c
new file mode 100644
index 0000000..a8c65e0
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer2_gl/timer2.c
@@ -0,0 +1,197 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+/*
+ * Timer2 Test --- This runs the same testbench as the
+ * other timer, on the 2nd counter/timer module instance.
+ */
+
+void main()
+{
+ int i;
+ uint32_t value;
+
+ /* Initialize output data vector to zero */
+ reg_mprj_datah = 0x00000000;
+ reg_mprj_datal = 0x00000000;
+
+ /* Apply all 38 bits to management standard output. */
+
+ /* The lower 32 will be used to output the count value */
+ /* from the timer. The top 5 bits will be used to mark */
+ /* specific checkpoints for the testbench simulation. */
+
+ reg_mprj_io_37 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_36 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_35 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_34 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_33 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_32 = GPIO_MODE_MGMT_STD_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_15 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_14 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_13 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_12 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_11 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_10 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_9 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_8 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_7 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_6 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_5 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_4 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_3 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_2 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_1 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ /* Present start marker (see testbench verilog) */
+ reg_mprj_datah = 0x0a;
+
+ /* Configure timer for a single-shot countdown */
+ reg_timer1_value = 0xdcba9876;
+
+ /* Timer configuration bits: */
+ /* 0 = timer enable (1 = enabled, 0 = disabled) */
+ /* 1 = one-shot mode (1 = oneshot, 0 = continuous) */
+ /* 2 = up/down (1 = count up, 0 = count down) */
+ /* 3 = IRQ enable (1 = enabled, 0 = disabled) */
+
+ reg_timer1_config = 3; /* Enabled, one-shot, down count */
+
+ for (i = 0; i < 8; i++) {
+ value = reg_timer1_data;
+ reg_mprj_datal = value; // Put count value on GPIO
+ }
+
+ reg_timer1_config = 0; /* Disabled */
+
+ reg_mprj_datah = 0x01; /* Check value in testbench */
+
+ reg_timer1_value = 0x00000011;
+ reg_timer1_config = 7; /* Enabled, one-shot, count up */
+
+ for (i = 0; i < 3; i++) {
+ value = reg_timer1_data;
+ reg_mprj_datal = value; // Put count value on GPIO
+ }
+
+ reg_mprj_datah = 0x02; /* Check value in testbench */
+
+ reg_timer1_data = 0x00000101; // Set value (will be reset)
+ reg_timer1_config = 2; /* Disabled, one-shot, count up */
+ reg_timer1_config = 5; /* Enabled, continuous, count down */
+
+ for (i = 0; i < 5; i++) {
+ value = reg_timer1_data;
+ reg_mprj_datal = value; // Put count value on GPIO
+ }
+
+ reg_mprj_datah = 0x03; /* Check value in testbench */
+
+ reg_timer1_data = 0x00000145; // Force new value
+
+ reg_mprj_datah = 0x04; /* Check value in testbench */
+
+ for (i = 0; i < 5; i++) {
+ value = reg_timer1_data;
+ reg_mprj_datal = value; // Put count value on GPIO
+ }
+
+ reg_mprj_datah = 0x05; /* Check value in testbench */
+
+ /* Now, set up chained 64 bit timer. Check count-up */
+ /* value and count-down value crossing the 32-bit */
+ /* boundary. */
+
+ /* First disable both counters, and set the "chained" */
+ /* property so that enable/disable will be synchronized */
+
+ reg_timer1_config = 8; /* Disabled, chained */
+ reg_timer0_config = 8; /* Disabled, chained */
+
+ /* Configure timer for a chained single-shot countdown. */
+ /* Count start = 0x0000000100001000, end = 0x0 */
+
+ reg_timer1_value = 0x00000055;
+ reg_timer0_value = 0x00001000;
+
+ /* Timer configuration bits: */
+ /* 0 = timer enable (1 = enabled, 0 = disabled) */
+ /* 1 = one-shot mode (1 = oneshot, 0 = continuous) */
+ /* 2 = up/down (1 = count up, 0 = count down) */
+ /* 3 = chain (1 = enabled, 0 = disabled) */
+ /* 4 = IRQ enable (1 = enabled, 0 = disabled) */
+
+ reg_timer1_config = 11; /* Enabled, one-shot, down count, chained */
+ reg_timer0_config = 11; /* Enabled, one-shot, down count, chained */
+
+ for (i = 0; i < 1; i++) {
+ value = reg_timer1_data;
+ reg_mprj_datal = value; // Put count value on GPIO
+ }
+
+ reg_mprj_datah = 0x06; /* Check value in testbench */
+
+ // Skip to the end. . .
+ reg_timer1_data = 0x00000000;
+ reg_timer0_data = 0x00000200;
+
+ for (i = 0; i < 4; i++) {
+ value = reg_timer0_data;
+ reg_mprj_datal = value; // Put count value on GPIO
+ }
+
+ reg_mprj_datah = 0x07; /* Check value in testbench */
+
+ reg_timer1_config = 14; /* Disabled, one-shot, up count, chained */
+ reg_timer0_config = 14; /* Disabled, one-shot, up count, chained */
+
+ reg_timer1_value = 0x00000002;
+ reg_timer0_value = 0x00000000;
+
+ reg_timer1_config = 15; /* Enabled, one-shot, up count, chained */
+ reg_timer0_config = 15; /* Enabled, one-shot, up count, chained */
+
+ for (i = 0; i < 1; i++) {
+ value = reg_timer0_data;
+ reg_mprj_datal = value; // Put count value on GPIO
+ }
+
+ reg_mprj_datah = 0x08; /* Check value in testbench */
+
+ // Skip to the end. . .
+ /* Count 0x00000001ffffff00 to 0x0000000200000000 and stop */
+
+ reg_timer1_data = 0x00000001; // Set value (will be reset)
+ reg_timer0_data = 0xffffff00; // Set value (will be reset)
+
+ for (i = 0; i < 4; i++) {
+ value = reg_timer1_data;
+ reg_mprj_datal = value; // Put timer1 count value on GPIO
+ }
+
+ /* Present end marker (see testbench verilog) */
+ reg_mprj_datah = 0x10;
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/timer2_gl/timer2_tb.v b/verilog/dv/caravel/mgmt_soc/timer2_gl/timer2_tb.v
new file mode 100644
index 0000000..00f3280
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer2_gl/timer2_tb.v
@@ -0,0 +1,214 @@
+`default_nettype none
+/*
+ * 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
+
+`define GL
+
+`include "caravel.v"
+`include "spiflash.v"
+
+module timer2_tb;
+
+ reg clock;
+ reg RSTB;
+ reg power1, power2;
+
+ always #10 clock <= (clock === 1'b0);
+
+ initial begin
+ clock <= 0;
+ end
+
+ initial begin
+ $dumpfile("timer2.vcd");
+ $dumpvars(0, timer2_tb);
+
+ // Repeat cycles of 1000 clock edges as needed to complete testbench
+ repeat (60) begin
+ repeat (1000) @(posedge clock);
+ $display("+1000 cycles");
+ end
+ $display("%c[1;31m",27);
+ $display ("Monitor: Timeout, Test GPIO (GL) Failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ wire [37:0] mprj_io; // Most of these are no-connects
+ wire [5:0] checkbits;
+ wire [31:0] countbits;
+
+ assign checkbits = mprj_io[37:32];
+ assign countbits = mprj_io[31:0];
+
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+ wire gpio;
+
+ // Monitor
+ initial begin
+ wait(checkbits == 6'h0a);
+ $display("Monitor: Test Timer2 (GL) Started");
+
+ /* Add checks here */
+ wait(checkbits == 6'h01);
+ $display(" countbits = 0x%x (should be 0xdcba7cf3)", countbits);
+ if(countbits !== 32'hdcba7cf3) begin
+ $display("Monitor: Test Timer2 (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 6'h02);
+ $display(" countbits = 0x%x (should be 0x11)", countbits);
+ if(countbits !== 32'h11) begin
+ $display("Monitor: Test Timer2 (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 6'h03);
+ $display(" countbits = %x (should be 0x0f)", countbits);
+ if(countbits !== 32'h0f) begin
+ $display("Monitor: Test Timer (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 6'h04);
+ $display(" countbits = %x (should be 0x0f)", countbits);
+ if(countbits !== 32'h0f) begin
+ $display("Monitor: Test Timer2 (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 6'h05);
+ $display(" countbits = %x (should be 0x12b4)", countbits);
+ if(countbits !== 32'h12b4) begin
+ $display("Monitor: Test Timer2 (GL) Failed");
+ $finish;
+ end
+
+ wait(checkbits == 6'h06);
+ $display(" countbits = %x (should be 0x0055)", countbits);
+ if(countbits !== 32'h0055) begin
+ $display("Monitor: Test Timer2 (GL) Failed");
+ $finish;
+ end
+
+ wait(checkbits == 6'h07);
+ $display(" countbits = %x (should be 0x0000)", countbits);
+ if(countbits !== 32'h0000) begin
+ $display("Monitor: Test Timer2 (GL) Failed");
+ $finish;
+ end
+
+ wait(checkbits == 6'h08);
+ $display(" countbits = %x (should be 0x0259)", countbits);
+ if(countbits !== 32'h0259) begin
+ $display("Monitor: Test Timer2 (GL) Failed");
+ $finish;
+ end
+
+ wait(checkbits == 6'h10);
+ $display(" countbits = %x (should be 0x0002)", countbits);
+ if(countbits !== 32'h0002) begin
+ $display("Monitor: Test Timer2 (GL) Failed");
+ $finish;
+ end
+
+ $display("Monitor: Test Timer2 (GL) Passed");
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+ #1000;
+ RSTB <= 1'b1; // Release reset
+ end
+
+ initial begin // Power-up sequence
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ end
+
+ always @(checkbits) begin
+ #1 $display("Timer state = %b (%d)", countbits, countbits);
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+ assign VSS = 1'b0;
+
+ // 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("timer2.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/caravel/mgmt_soc/timer_gl/Makefile b/verilog/dv/caravel/mgmt_soc/timer_gl/Makefile
new file mode 100644
index 0000000..92e809f
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer_gl/Makefile
@@ -0,0 +1,43 @@
+FIRMWARE_PATH = ../..
+RTL_PATH = ../../../../rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = timer
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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_gl/timer.c b/verilog/dv/caravel/mgmt_soc/timer_gl/timer.c
new file mode 100644
index 0000000..c3a8dc4
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer_gl/timer.c
@@ -0,0 +1,124 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+/*
+ * Timer Test
+ */
+
+void main()
+{
+ int i;
+ uint32_t value;
+
+ /* Initialize output data vector to zero */
+ reg_mprj_datah = 0x00000000;
+ reg_mprj_datal = 0x00000000;
+
+ /* Apply all 38 bits to management standard output. */
+
+ /* The lower 32 will be used to output the count value */
+ /* from the timer. The top 5 bits will be used to mark */
+ /* specific checkpoints for the testbench simulation. */
+
+ reg_mprj_io_37 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_36 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_35 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_34 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_33 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_32 = GPIO_MODE_MGMT_STD_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_15 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_14 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_13 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_12 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_11 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_10 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_9 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_8 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_7 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_6 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_5 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_4 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_3 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_2 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_1 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ /* Present start marker (see testbench verilog) */
+ reg_mprj_datah = 0x0a;
+
+ /* Configure timer for a single-shot countdown */
+ reg_timer0_value = 0xdcba9876;
+
+ /* Timer configuration bits: */
+ /* 0 = timer enable (1 = enabled, 0 = disabled) */
+ /* 1 = one-shot mode (1 = oneshot, 0 = continuous) */
+ /* 2 = up/down (1 = count up, 0 = count down) */
+ /* 3 = chain (1 = enabled, 0 = disabled) */
+ /* 4 = IRQ enable (1 = enabled, 0 = disabled) */
+
+ reg_timer0_config = 3; /* Enabled, one-shot, down count */
+
+ for (i = 0; i < 8; i++) {
+ value = reg_timer0_data;
+ reg_mprj_datal = value; // Put count value on GPIO
+ }
+
+ reg_timer0_config = 0; /* Disabled */
+
+ reg_mprj_datah = 0x01; /* Check value in testbench */
+
+ reg_timer0_value = 0x00000011;
+ reg_timer0_config = 7; /* Enabled, one-shot, count up */
+
+ for (i = 0; i < 3; i++) {
+ value = reg_timer0_data;
+ reg_mprj_datal = value; // Put count value on GPIO
+ }
+
+ reg_mprj_datah = 0x02; /* Check value in testbench */
+
+ reg_timer0_data = 0x00000101; // Set value (will be reset)
+ reg_timer0_config = 2; /* Disabled, one-shot, count up */
+ reg_timer0_config = 5; /* Enabled, continuous, count down */
+
+ for (i = 0; i < 5; i++) {
+ value = reg_timer0_data;
+ reg_mprj_datal = value; // Put count value on GPIO
+ }
+
+ reg_mprj_datah = 0x03; /* Check value in testbench */
+
+ reg_timer0_data = 0x00000145; // Force new value
+
+ reg_mprj_datah = 0x04; /* Check value in testbench */
+
+ for (i = 0; i < 5; i++) {
+ value = reg_timer0_data;
+ reg_mprj_datal = value; // Put count value on GPIO
+ }
+
+ /* Present end marker (see testbench verilog) */
+ reg_mprj_datah = 0x05;
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/timer_gl/timer_tb.v b/verilog/dv/caravel/mgmt_soc/timer_gl/timer_tb.v
new file mode 100644
index 0000000..30904d6
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer_gl/timer_tb.v
@@ -0,0 +1,186 @@
+`default_nettype none
+/*
+ * 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
+
+`define GL
+
+`include "caravel.v"
+`include "spiflash.v"
+
+module timer_tb;
+
+ reg RSTB;
+ reg clock;
+ reg power1, power2;
+
+ 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 (50) begin
+ repeat (1000) @(posedge clock);
+ $display("+1000 cycles");
+ end
+ $display("%c[1;31m",27);
+ $display ("Monitor: Timeout, Test GPIO (GL) Failed");
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ wire [37:0] mprj_io; // Most of these are no-connects
+ wire [5:0] checkbits;
+ wire [31:0] countbits;
+
+ assign checkbits = mprj_io[37:32];
+ assign countbits = mprj_io[31:0];
+
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+ wire gpio;
+
+ // Monitor
+ initial begin
+ wait(checkbits == 6'h0a);
+ $display("Monitor: Test Timer (GL) Started");
+
+ /* Add checks here */
+ wait(checkbits == 6'h01);
+ $display(" countbits = 0x%x (should be 0xdcba7cf3)", countbits);
+ if(countbits !== 32'hdcba7cf3) begin
+ $display("Monitor: Test Timer (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 6'h02);
+ $display(" countbits = 0x%x (should be 0x11)", countbits);
+ if(countbits !== 32'h11) begin
+ $display("Monitor: Test Timer (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 6'h03);
+ $display(" countbits = %x (should be 0x0f)", countbits);
+ if(countbits !== 32'h0f) begin
+ $display("Monitor: Test Timer (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 6'h04);
+ $display(" countbits = %x (should be 0x0f)", countbits);
+ if(countbits !== 32'h0f) begin
+ $display("Monitor: Test Timer (GL) Failed");
+ $finish;
+ end
+ wait(checkbits == 6'h05);
+ $display(" countbits = %x (should be 0x12b4)", countbits);
+ if(countbits !== 32'h12b4) begin
+ $display("Monitor: Test Timer (GL) Failed");
+ $finish;
+ end
+
+ $display("Monitor: Test Timer (GL) Passed");
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+ #1000;
+ RSTB <= 1'b1; // Release reset
+ end
+
+ initial begin // Power-up sequence
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ end
+
+ always @(checkbits) begin
+ #1 $display("Timer state = %b (%d)", countbits, countbits);
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+ assign VSS = 1'b0;
+
+ // 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
+`default_nettype wire
diff --git a/verilog/dv/caravel/mgmt_soc/uart_gl/Makefile b/verilog/dv/caravel/mgmt_soc/uart_gl/Makefile
new file mode 100644
index 0000000..004a876
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/uart_gl/Makefile
@@ -0,0 +1,44 @@
+# ---- Test patterns for project striVe ----
+FIRMWARE_PATH = ../..
+RTL_PATH = ../../../../rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+.SUFFIXES:
+
+PATTERN = uart
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \
+ $< -o $@
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-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/uart_gl/uart.c b/verilog/dv/caravel/mgmt_soc/uart_gl/uart.c
new file mode 100644
index 0000000..3f8d4c9
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/uart_gl/uart.c
@@ -0,0 +1,59 @@
+#include "../../defs.h"
+#include "../../stub.c"
+
+// --------------------------------------------------------
+
+void main()
+{
+ int j;
+
+ // 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;
+
+ // Set clock to 64 kbaud and enable the UART. It is important to do this
+ // before applying the configuration, or else the Tx line initializes as
+ // zero, which indicates the start of a byte to the receiver.
+
+ reg_uart_clkdiv = 625;
+ reg_uart_enable = 1;
+
+ // Now, apply the configuration
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ // Start test
+ reg_mprj_datal = 0xa0000000;
+
+ // This should appear at the output, received by the testbench UART.
+ // (Makes simulation time long.)
+ print("Monitor: Test UART (RTL) passed\n");
+
+ // Allow transmission to complete before signalling that the program
+ // has ended.
+ for (j = 0; j < 20; j++);
+ reg_mprj_datal = 0xab000000;
+}
diff --git a/verilog/dv/caravel/mgmt_soc/uart_gl/uart_tb.v b/verilog/dv/caravel/mgmt_soc/uart_gl/uart_tb.v
new file mode 100644
index 0000000..b034591
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/uart_gl/uart_tb.v
@@ -0,0 +1,142 @@
+`default_nettype none
+/*
+ * 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
+
+`define GL
+
+`include "caravel.v"
+`include "spiflash.v"
+`include "tbuart.v"
+
+module uart_tb;
+ reg clock;
+ reg RSTB;
+ reg power1, power2;
+
+ wire gpio;
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+ wire [37:0] mprj_io;
+ wire [15:0] checkbits;
+ wire uart_tx;
+ wire SDO;
+
+ assign checkbits = mprj_io[31:16];
+ assign uart_tx = mprj_io[6];
+
+ always #12.5 clock <= (clock === 1'b0);
+
+ initial begin
+ clock = 0;
+ end
+
+ initial begin
+ $dumpfile("uart.vcd");
+ $dumpvars(0, uart_tb);
+
+ $display("Wait for UART o/p");
+ repeat (150) begin
+ repeat (10000) @(posedge clock);
+ // Diagnostic. . . interrupts output pattern.
+ end
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+ #1000;
+ RSTB <= 1'b1; // Release reset
+ #2000;
+ end
+
+ initial begin // Power-up sequence
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ end
+
+ always @(checkbits) begin
+ if(checkbits == 16'hA000) begin
+ $display("UART Test (GL) started");
+ end
+ else if(checkbits == 16'hAB00) begin
+ $display("UART Test (GL) passed");
+ $finish;
+ end
+ end
+
+ wire VDD3V3;
+ wire VDD1V8;
+ wire VSS;
+
+ assign VDD3V3 = power1;
+ assign VDD1V8 = power2;
+ assign VSS = 1'b0;
+
+ 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("uart.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+ // Testbench UART
+ tbuart tbuart (
+ .ser_rx(uart_tx)
+ );
+
+endmodule
+`default_nettype wire
diff --git a/verilog/gl/mgmt_core.v.gz b/verilog/gl/mgmt_core.v.gz
index dcdce46..f26ccea 100644
--- a/verilog/gl/mgmt_core.v.gz
+++ b/verilog/gl/mgmt_core.v.gz
Binary files differ
diff --git a/verilog/rtl/caravel.v b/verilog/rtl/caravel.v
index bd3a167..46cfdfd 100644
--- a/verilog/rtl/caravel.v
+++ b/verilog/rtl/caravel.v
@@ -30,11 +30,16 @@
`include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
`include "libs.ref/sky130_fd_sc_hvl/verilog/sky130_fd_sc_hvl.v"
-`include "mgmt_soc.v"
-`include "housekeeping_spi.v"
+`ifdef GL
+ `include "gl/mgmt_core.v"
+`else
+ `include "mgmt_soc.v"
+ `include "housekeeping_spi.v"
+ `include "caravel_clocking.v"
+ `include "mgmt_core.v"
+`endif
+
`include "digital_pll.v"
-`include "caravel_clocking.v"
-`include "mgmt_core.v"
`include "mgmt_protect.v"
`include "mgmt_protect_hv.v"
`include "mprj_io.v"
@@ -356,8 +361,8 @@
mgmt_core soc (
`ifdef USE_POWER_PINS
- .vdd1v8(vccd),
- .vss(vssa),
+ .VPWR(vccd),
+ .VGND(vssa),
`endif
// GPIO (1 pin)
.gpio_out_pad(gpio_out_core),
diff --git a/verilog/rtl/digital_pll.v b/verilog/rtl/digital_pll.v
index 2f3fc2a..9840a7d 100644
--- a/verilog/rtl/digital_pll.v
+++ b/verilog/rtl/digital_pll.v
@@ -7,14 +7,14 @@
module digital_pll(
`ifdef USE_POWER_PINS
- vdd,
- vss,
+ VPWR,
+ VGND,
`endif
resetb, enable, osc, clockp, div, dco, ext_trim);
`ifdef USE_POWER_PINS
- input vdd;
- input vss;
+ input VPWR;
+ input VGND;
`endif
input resetb; // Sense negative reset
diff --git a/verilog/rtl/mgmt_core.v b/verilog/rtl/mgmt_core.v
index 2f8b45d..56ba46b 100644
--- a/verilog/rtl/mgmt_core.v
+++ b/verilog/rtl/mgmt_core.v
@@ -1,8 +1,8 @@
`default_nettype none
module mgmt_core (
`ifdef USE_POWER_PINS
- inout vdd1v8,
- inout vss,
+ inout VPWR,
+ inout VGND,
`endif
// GPIO (dedicated pad)
output gpio_out_pad, // Connect to out on gpio pad
@@ -168,8 +168,8 @@
mgmt_soc soc (
`ifdef USE_POWER_PINS
- .vdd1v8(vdd1v8),
- .vss(vss),
+ .vdd1v8(VPWR),
+ .vss(VGND),
`endif
.clk(core_clk),
.resetn(core_rstn),