Added and verified testbenches timer, timer2, uart, and user_pass_thru.

This commit is contained in:
Tim Edwards 2021-10-18 21:53:09 -04:00
parent 0fa2e3bb89
commit e2f6a02688
14 changed files with 1893 additions and 0 deletions

View File

@ -0,0 +1,86 @@
# SPDX-FileCopyrightText: 2020 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
PDK_PATH = $(PDK_ROOT)/sky130A
VERILOG_PATH = ../../../..
RTL_PATH = $(VERILOG_PATH)/rtl
BEHAVIOURAL_MODELS = ../../
# Temporary: Path to management SoC wrapper repository
MGMT_WRAPPER_PATH = ~/gits/caravel_pico/verilog/rtl
FIRMWARE_PATH = ../..
GCC_PATH?=/ef/apps/bin
GCC_PREFIX?=riscv32-unknown-elf
SIM_DEFINES = -DFUNCTIONAL -DSIM
SIM?=RTL
.SUFFIXES:
PATTERN = timer
all: ${PATTERN:=.vcd}
hex: ${PATTERN:=.hex}
%.vvp: %_tb.v %.hex
ifeq ($(SIM),RTL)
iverilog -Ttyp $(SIM_DEFINES) -I $(BEHAVIOURAL_MODELS) \
-I $(PDK_PATH) -I $(RTL_PATH) -I $(MGMT_WRAPPER_PATH) \
$< -o $@
else
iverilog -Ttyp $(SIM_DEFINES) -DGL -I $(BEHAVIOURAL_MODELS) \
-I $(PDK_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
$< -o $@
endif
%.vcd: %.vvp
vvp $<
%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s check-env
${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 > $@
check-env:
ifndef PDK_ROOT
$(error PDK_ROOT is undefined, please export it before running make)
endif
ifeq (,$(wildcard $(PDK_ROOT)/sky130A))
$(error $(PDK_ROOT)/sky130A not found, please install pdk before running make)
endif
ifeq (,$(wildcard $(GCC_PATH)/$(GCC_PREFIX)-gcc ))
$(error $(GCC_PATH)/$(GCC_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make)
endif
# check for efabless style installation
ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog))
SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE
endif
# ---- Clean ----
clean:
rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
.PHONY: clean hex all

View File

@ -0,0 +1,141 @@
/*
* SPDX-FileCopyrightText: 2020 Efabless Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0
*/
#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;
}

View File

@ -0,0 +1,201 @@
`default_nettype none
/*
* SPDX-FileCopyrightText: 2017 Clifford Wolf, 2018 Tim Edwards
*
* 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.
*
* SPDX-License-Identifier: ISC
*/
`timescale 1 ns / 1 ps
`include "__uprj_netlists.v"
`include "caravel_netlists.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);
`ifdef GL
$display ("Monitor: Timeout, Test GPIO (GL) Failed");
`else
$display ("Monitor: Timeout, Test GPIO (RTL) Failed");
`endif
$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];
assign mprj_io[3] = 1'b1; // Force CSB high.
wire flash_csb;
wire flash_clk;
wire flash_io0;
wire flash_io1;
wire gpio;
// Monitor
initial begin
wait(checkbits == 6'h0a);
`ifdef GL
$display("Monitor: Test Timer (GL) Started");
`else
$display("Monitor: Test Timer (RTL) Started");
`endif
/* Add checks here */
wait(checkbits == 6'h01);
$display(" countbits = 0x%x (should be 0xdcba7cf9)", countbits);
if(countbits !== 32'hdcba7cf9) begin
$display("Monitor: Test Timer Failed");
$finish;
end
wait(checkbits == 6'h02);
$display(" countbits = 0x%x (should be 0x19)", countbits);
if(countbits !== 32'h19) begin
$display("Monitor: Test Timer Failed");
$finish;
end
wait(checkbits == 6'h03);
$display(" countbits = %x (should be 0x0d)", countbits);
if(countbits !== ((32'h0d) | (3'b100))) begin
$display("Monitor: Test Timer Failed");
$finish;
end
wait(checkbits == 6'h04);
$display(" countbits = %x (should be 0x0d)", countbits);
if(countbits !== ((32'h0d) | (3'b100))) begin
$display("Monitor: Test Timer Failed");
$finish;
end
wait(checkbits == 6'h05);
$display(" countbits = %x (should be 0x12bc)", countbits);
if(countbits !== 32'h12bc) begin
$display("Monitor: Test Timer Failed");
$finish;
end
`ifdef GL
$display("Monitor: Test Timer (GL) Passed");
`else
$display("Monitor: Test Timer (RTL) Passed");
`endif
$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

View File

@ -0,0 +1,86 @@
# SPDX-FileCopyrightText: 2020 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
PDK_PATH = $(PDK_ROOT)/sky130A
VERILOG_PATH = ../../../..
RTL_PATH = $(VERILOG_PATH)/rtl
BEHAVIOURAL_MODELS = ../../
# Temporary: Path to management SoC wrapper repository
MGMT_WRAPPER_PATH = ~/gits/caravel_pico/verilog/rtl
FIRMWARE_PATH = ../..
GCC_PATH?=/ef/apps/bin
GCC_PREFIX?=riscv32-unknown-elf
SIM_DEFINES = -DFUNCTIONAL -DSIM
SIM?=RTL
.SUFFIXES:
PATTERN = timer2
all: ${PATTERN:=.vcd}
hex: ${PATTERN:=.hex}
%.vvp: %_tb.v %.hex
ifeq ($(SIM),RTL)
iverilog -Ttyp $(SIM_DEFINES) -I $(BEHAVIOURAL_MODELS) \
-I $(PDK_PATH) -I $(RTL_PATH) -I $(MGMT_WRAPPER_PATH) \
$< -o $@
else
iverilog -Ttyp $(SIM_DEFINES) -DGL -I $(BEHAVIOURAL_MODELS) \
-I $(PDK_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
$< -o $@
endif
%.vcd: %.vvp
vvp $<
%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s check-env
${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 > $@
check-env:
ifndef PDK_ROOT
$(error PDK_ROOT is undefined, please export it before running make)
endif
ifeq (,$(wildcard $(PDK_ROOT)/sky130A))
$(error $(PDK_ROOT)/sky130A not found, please install pdk before running make)
endif
ifeq (,$(wildcard $(GCC_PATH)/$(GCC_PREFIX)-gcc ))
$(error $(GCC_PATH)/$(GCC_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make)
endif
# check for efabless style installation
ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog))
SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE
endif
# ---- Clean ----
clean:
rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
.PHONY: clean hex all

View File

@ -0,0 +1,214 @@
/*
* SPDX-FileCopyrightText: 2020 Efabless Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0
*/
#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;
}

View File

@ -0,0 +1,229 @@
`default_nettype none
/*
* SPDX-FileCopyrightText: 2017 Clifford Wolf, 2018 Tim Edwards
*
* 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.
*
* SPDX-License-Identifier: ISC
*/
`timescale 1 ns / 1 ps
`include "__uprj_netlists.v"
`include "caravel_netlists.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);
`ifdef GL
$display ("Monitor: Timeout, Test Timer2 (GL) Failed");
`else
$display ("Monitor: Timeout, Test Timer2 (RTL) Failed");
`endif
$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);
`ifdef GL
$display("Monitor: Test Timer2 (GL) Started");
`else
$display("Monitor: Test Timer2 (RTL) Started");
`endif
/* Add checks here */
wait(checkbits == 6'h01);
$display(" countbits = 0x%x (should be 0xdcba7cf9)", countbits);
if(countbits !== 32'hdcba7cf9) begin
$display("Monitor: Test Timer2 (RTL) Failed");
$finish;
end
wait(checkbits == 6'h02);
$display(" countbits = 0x%x (should be 0x19)", countbits);
if(countbits !== 32'h19) begin
$display("Monitor: Test Timer2 (RTL) Failed");
$finish;
end
wait(checkbits == 6'h03);
$display(" countbits = %x (should be 0x0d)", countbits);
if(countbits !== 32'h0d) begin
$display("Monitor: Test Timer (RTL) Failed");
$finish;
end
wait(checkbits == 6'h04);
$display(" countbits = %x (should be 0x0d)", countbits);
if(countbits !== 32'h0d) begin
$display("Monitor: Test Timer2 (RTL) Failed");
$finish;
end
wait(checkbits == 6'h05);
$display(" countbits = %x (should be 0x12bc)", countbits);
if(countbits !== 32'h12bc) begin
$display("Monitor: Test Timer2 (RTL) Failed");
$finish;
end
wait(checkbits == 6'h06);
$display(" countbits = %x (should be 0x005d)", countbits);
if(countbits !== 32'h005d) begin
$display("Monitor: Test Timer2 (RTL) Failed");
$finish;
end
wait(checkbits == 6'h07);
$display(" countbits = %x (should be 0x0008)", countbits);
if(countbits !== 32'h0008) begin
$display("Monitor: Test Timer2 (RTL) Failed");
$finish;
end
wait(checkbits == 6'h08);
$display(" countbits = %x (should be 0x0259)", countbits);
if(countbits !== 32'h0259) begin
$display("Monitor: Test Timer2 (RTL) Failed");
$finish;
end
wait(checkbits == 6'h10);
$display(" countbits = %x (should be 0x0008)", countbits);
if(countbits !== 32'h0008) begin
$display("Monitor: Test Timer2 (RTL) Failed");
$finish;
end
`ifdef GL
$display("Monitor: Test Timer2 (GL) Passed");
`else
$display("Monitor: Test Timer2 (RTL) Passed");
`endif
$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;
assign mprj_io[3] = 1'b1; // Force CSB high.
// 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

View File

@ -0,0 +1,86 @@
# SPDX-FileCopyrightText: 2020 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
PDK_PATH = $(PDK_ROOT)/sky130A
VERILOG_PATH = ../../../..
RTL_PATH = $(VERILOG_PATH)/rtl
BEHAVIOURAL_MODELS = ../../
# Temporary: Path to management SoC wrapper repository
MGMT_WRAPPER_PATH = ~/gits/caravel_pico/verilog/rtl
FIRMWARE_PATH = ../..
GCC_PATH?=/ef/apps/bin
GCC_PREFIX?=riscv32-unknown-elf
SIM_DEFINES = -DFUNCTIONAL -DSIM
SIM?=RTL
.SUFFIXES:
PATTERN = uart
all: ${PATTERN:=.vcd}
hex: ${PATTERN:=.hex}
%.vvp: %_tb.v %.hex
ifeq ($(SIM),RTL)
iverilog -Ttyp $(SIM_DEFINES) -I $(BEHAVIOURAL_MODELS) \
-I $(PDK_PATH) -I $(RTL_PATH) -I $(MGMT_WRAPPER_PATH) \
$< -o $@
else
iverilog -Ttyp $(SIM_DEFINES) -DGL -I $(BEHAVIOURAL_MODELS) \
-I $(PDK_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
$< -o $@
endif
%.vcd: %.vvp
vvp $<
%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s check-env
${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 > $@
check-env:
ifndef PDK_ROOT
$(error PDK_ROOT is undefined, please export it before running make)
endif
ifeq (,$(wildcard $(PDK_ROOT)/sky130A))
$(error $(PDK_ROOT)/sky130A not found, please install pdk before running make)
endif
ifeq (,$(wildcard $(GCC_PATH)/$(GCC_PREFIX)-gcc ))
$(error $(GCC_PATH)/$(GCC_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make)
endif
# check for efabless style installation
ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog))
SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE
endif
# ---- Clean ----
clean:
rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
.PHONY: clean hex all

View File

@ -0,0 +1,76 @@
/*
* SPDX-FileCopyrightText: 2020 Efabless Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0
*/
#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;
}

View File

@ -0,0 +1,150 @@
`default_nettype none
/*
* SPDX-FileCopyrightText: 2017 Clifford Wolf, 2018 Tim Edwards
*
* 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.
*
* SPDX-License-Identifier: ISC
*/
`timescale 1 ns / 1 ps
`include "__uprj_netlists.v"
`include "caravel_netlists.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 started");
end
else if(checkbits == 16'hAB00) begin
`ifdef GL
$display("UART Test (GL) passed");
`else
$display("UART Test (RTL) passed");
`endif
$finish;
end
end
wire VDD3V3;
wire VDD1V8;
wire VSS;
assign VDD3V3 = power1;
assign VDD1V8 = power2;
assign VSS = 1'b0;
assign mprj_io[3] = 1'b1; // Force CSB high.
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

View File

@ -0,0 +1,86 @@
# SPDX-FileCopyrightText: 2020 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
PDK_PATH = $(PDK_ROOT)/sky130A
VERILOG_PATH = ../../../..
RTL_PATH = $(VERILOG_PATH)/rtl
BEHAVIOURAL_MODELS = ../../
# Temporary: Path to management SoC wrapper repository
MGMT_WRAPPER_PATH = ~/gits/caravel_pico/verilog/rtl
FIRMWARE_PATH = ../..
GCC_PATH?=/ef/apps/bin
GCC_PREFIX?=riscv32-unknown-elf
SIM_DEFINES = -DFUNCTIONAL -DSIM
SIM?=RTL
.SUFFIXES:
PATTERN = user_pass_thru
all: ${PATTERN:=.vcd}
hex: ${PATTERN:=.hex}
%.vvp: %_tb.v %.hex
ifeq ($(SIM),RTL)
iverilog -Ttyp $(SIM_DEFINES) -I $(BEHAVIOURAL_MODELS) \
-I $(PDK_PATH) -I $(RTL_PATH) -I $(MGMT_WRAPPER_PATH) \
$< -o $@
else
iverilog -Ttyp $(SIM_DEFINES) -DGL -I $(BEHAVIOURAL_MODELS) \
-I $(PDK_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \
$< -o $@
endif
%.vcd: %.vvp
vvp $<
%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s check-env
${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 > $@
check-env:
ifndef PDK_ROOT
$(error PDK_ROOT is undefined, please export it before running make)
endif
ifeq (,$(wildcard $(PDK_ROOT)/sky130A))
$(error $(PDK_ROOT)/sky130A not found, please install pdk before running make)
endif
ifeq (,$(wildcard $(GCC_PATH)/$(GCC_PREFIX)-gcc ))
$(error $(GCC_PATH)/$(GCC_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make)
endif
# check for efabless style installation
ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog))
SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE
endif
# ---- Clean ----
clean:
rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
.PHONY: clean hex all

View File

@ -0,0 +1,14 @@
------------------------------------
user_pass_thru test bench
------------------------------------
This test bench exercises the pass-thru mode to the GPIO pins
that are reserved for use by a user project for connecting to
an SPI flash. The pass-thru mode allows the SPI flash to be
programmed using the housekeeping SPI.
The testbench is essentially the same as the pass_thru test
bench, but using the pins specified for the secondary SPI
flash. Note that the testbench does not define a controller
on the user side to access the SPI flash (which would be a
useful thing to add to the testbench).

View File

@ -0,0 +1,96 @@
/*
* SPDX-FileCopyrightText: 2020 Efabless Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0
*/
#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;
// Management needs to apply output on these pads to access the user area SPI flash
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_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;
}

View File

@ -0,0 +1,399 @@
// SPDX-FileCopyrightText: 2020 Efabless Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0
`default_nettype none
/*
* StriVe housekeeping pass-thru mode SPI testbench.
*/
`timescale 1 ns / 1 ps
`include "__uprj_netlists.v"
`include "caravel_netlists.v"
`include "spiflash.v"
`include "tbuart.v"
module user_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 user_csb;
wire user_clk;
wire user_io0;
wire user_io1;
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("user_pass_thru.vcd");
$dumpvars(0, user_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 0x11)", tbdata);
if(tbdata !== 8'h11) begin
`ifdef GL
$display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish;
`endif
end
// The SPI flash may need to be reset.
start_csb();
write_byte(8'hc2); // Apply user pass-thru command to housekeeping SPI
write_byte(8'hff); // SPI flash command ff
end_csb();
start_csb();
write_byte(8'hc2); // Apply user pass-thru command to housekeeping SPI
write_byte(8'hab); // SPI flash command ab
end_csb();
start_csb();
write_byte(8'hc2); // Apply user pass-thru command to housekeeping SPI
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
`ifdef GL
$display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read flash data = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read flash data = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read flash data = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read flash data = 0x%02x (should be 0x93)", tbdata);
if(tbdata !== 8'h93) begin
`ifdef GL
$display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read flash data = 0x%02x (should be 0x01)", tbdata);
if(tbdata !== 8'h01) begin
`ifdef GL
$display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read flash data = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read flash data = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish;
`endif
end
end_csb();
// Reset processor
start_csb();
write_byte(8'h80); // Write stream command
write_byte(8'h0b); // Address (register 11 = reset)
write_byte(8'h01); // Data (value 1 = apply reset)
end_csb();
start_csb();
write_byte(8'h80); // Write stream command
write_byte(8'h0b); // Address (register 11 = reset)
write_byte(8'h00); // Data (value 1 = apply reset)
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 0x11)", tbdata);
if(tbdata !== 8'h11) begin
`ifdef GL
$display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish;
`endif
end
`ifdef GL
$display("Monitor: Test HK SPI Pass-thru (GL) Passed");
`else
$display("Monitor: Test HK SPI Pass-thru (RTL) Passed");
`endif
#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];
assign user_csb = mprj_io[8];
assign user_clk = mprj_io[9];
assign user_io0 = mprj_io[10];
assign mprj_io[11] = user_io1;
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("user_pass_thru.hex")
) spiflash (
.csb(flash_csb),
.clk(flash_clk),
.io0(flash_io0),
.io1(flash_io1),
.io2(), // not used
.io3() // not used
);
// Use the same flash; this is just to put known data in memory that can be
// checked by reading it back through a pass-through command.
spiflash #(
.FILENAME("user_pass_thru.hex")
) secondary (
.csb(user_csb),
.clk(user_clk),
.io0(user_io0),
.io1(user_io1),
.io2(), // not used
.io3() // not used
);
tbuart tbuart (
.ser_rx(uart_tx)
);
endmodule
`default_nettype wire

29
verilog/dv/caravel/stub.c Normal file
View File

@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2020 Efabless Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0
*/
void putchar(char c)
{
if (c == '\n')
putchar('\r');
reg_uart_data = c;
}
void print(const char *p)
{
while (*p)
putchar(*(p++));
}