mirror of https://github.com/efabless/caravel.git
Added and verified testbenches timer, timer2, uart, and user_pass_thru.
This commit is contained in:
parent
0fa2e3bb89
commit
e2f6a02688
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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).
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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++));
|
||||||
|
}
|
Loading…
Reference in New Issue