Added and debugged two more testbenches, gpio_mgmt and hkspi.

This commit is contained in:
Tim Edwards 2021-10-18 11:25:26 -04:00
parent 33ca4e11ef
commit 2e57b5da08
9 changed files with 1641 additions and 579 deletions

View File

@ -10,104 +10,112 @@ SPI register description signal memory map address
05 User project ID mask_rev[23:16] 2610_000a
06 User project ID mask_rev[15:8] 2610_0009
07 User project ID mask_rev[7:0] 2610_0008
08 CPU trap state trap 2610_000c
09 Power monitor usr1/2_vcc/vdd_pwrgood 2620_0000
0a Output redirect clk1/clk2/trap_output_dest 2620_0004
0b Input redirect irq_8/7_inputsrc 2620_000c
08 PLL enables pll_dco_ena, pll_ena 2610_000c
09 PLL bypass pll_bypass 2610_0010
0a IRQ irq 2610_0014
0b Reset reset 2610_0018
0c CPU trap state trap 2610_0028
0d PLL trim pll_trim[31:24] 2610_001f
0e PLL trim pll_trim[23:16] 2610_001e
0f PLL trim pll_trim[15:8] 2610_001d
10 PLL trim pll_trim[7:0] 2610_001c
11 PLL source pll90_sel[2:0], pll_sel[2:0] 2610_0020
12 PLL divider pll_div[4:0] 2610_0024
13 GPIO control serial_resetn/clock/data 2600_0000
0c GPIO[0] configure gpio_configure[0][12:8] 2600_0025
0d GPIO[0] configure gpio_configure[0][7:0] 2600_0024
0e GPIO[1] configure gpio_configure[1][12:8] 2600_0029
0f GPIO[1] configure gpio_configure[1][7:0] 2600_0028
10 GPIO[2] configure gpio_configure[2][12:8] 2600_002d
11 GPIO[2] configure gpio_configure[2][7:0] 2600_002c
12 GPIO[3] configure gpio_configure[3][12:8] 2600_0031
13 GPIO[3] configure gpio_configure[3][7:0] 2600_0030
14 GPIO[4] configure gpio_configure[4][12:8] 2600_0035
15 GPIO[4] configure gpio_configure[4][7:0] 2600_0034
16 GPIO[5] configure gpio_configure[5][12:8] 2600_0039
17 GPIO[5] configure gpio_configure[5][7:0] 2600_0038
18 GPIO[6] configure gpio_configure[6][12:8] 2600_003d
19 GPIO[6] configure gpio_configure[6][7:0] 2600_003c
1a GPIO[7] configure gpio_configure[7][12:8] 2600_0041
1b GPIO[7] configure gpio_configure[7][7:0] 2600_0040
1c GPIO[8] configure gpio_configure[8][12:8] 2600_0045
1d GPIO[8] configure gpio_configure[8][7:0] 2600_0044
1e GPIO[9] configure gpio_configure[9][12:8] 2600_0049
1f GPIO[9] configure gpio_configure[9][7:0] 2600_0048
20 GPIO[10] configure gpio_configure[10][12:8] 2600_004d
21 GPIO[10] configure gpio_configure[10][7:0] 2600_004c
22 GPIO[11] configure gpio_configure[11][12:8] 2600_0051
23 GPIO[11] configure gpio_configure[11][7:0] 2600_0050
24 GPIO[12] configure gpio_configure[12][12:8] 2600_0055
25 GPIO[12] configure gpio_configure[12][7:0] 2600_0054
26 GPIO[13] configure gpio_configure[13][12:8] 2600_0059
27 GPIO[13] configure gpio_configure[13][7:0] 2600_0058
28 GPIO[14] configure gpio_configure[14][12:8] 2600_005d
29 GPIO[14] configure gpio_configure[14][7:0] 2600_005c
2a GPIO[15] configure gpio_configure[15][12:8] 2600_0061
2b GPIO[15] configure gpio_configure[15][7:0] 2600_0060
2c GPIO[16] configure gpio_configure[16][12:8] 2600_0065
2d GPIO[16] configure gpio_configure[16][7:0] 2600_0064
2e GPIO[17] configure gpio_configure[17][12:8] 2600_0069
2f GPIO[17] configure gpio_configure[17][7:0] 2600_0068
30 GPIO[18] configure gpio_configure[18][12:8] 2600_006d
31 GPIO[18] configure gpio_configure[18][7:0] 2600_006c
32 GPIO[19] configure gpio_configure[19][12:8] 2600_0071
33 GPIO[19] configure gpio_configure[19][7:0] 2600_0070
34 GPIO[20] configure gpio_configure[20][12:8] 2600_0075
35 GPIO[20] configure gpio_configure[20][7:0] 2600_0074
36 GPIO[21] configure gpio_configure[21][12:8] 2600_0079
37 GPIO[21] configure gpio_configure[21][7:0] 2600_0078
38 GPIO[22] configure gpio_configure[22][12:8] 2600_007d
39 GPIO[22] configure gpio_configure[22][7:0] 2600_007c
3a GPIO[23] configure gpio_configure[23][12:8] 2600_0081
3b GPIO[23] configure gpio_configure[23][7:0] 2600_0080
3c GPIO[24] configure gpio_configure[24][12:8] 2600_0085
3d GPIO[24] configure gpio_configure[24][7:0] 2600_0084
3e GPIO[25] configure gpio_configure[25][12:8] 2600_0089
3f GPIO[25] configure gpio_configure[25][7:0] 2600_0088
40 GPIO[26] configure gpio_configure[26][12:8] 2600_008d
41 GPIO[26] configure gpio_configure[26][7:0] 2600_008c
42 GPIO[27] configure gpio_configure[27][12:8] 2600_0091
43 GPIO[27] configure gpio_configure[27][7:0] 2600_0090
44 GPIO[28] configure gpio_configure[28][12:8] 2600_0095
45 GPIO[28] configure gpio_configure[28][7:0] 2600_0094
46 GPIO[29] configure gpio_configure[29][12:8] 2600_0099
47 GPIO[29] configure gpio_configure[29][7:0] 2600_0098
48 GPIO[30] configure gpio_configure[30][12:8] 2600_009d
49 GPIO[30] configure gpio_configure[30][7:0] 2600_009c
4a GPIO[31] configure gpio_configure[31][12:8] 2600_00a1
4b GPIO[31] configure gpio_configure[31][7:0] 2600_00a0
4c GPIO[32] configure gpio_configure[32][12:8] 2600_00a5
4d GPIO[32] configure gpio_configure[32][7:0] 2600_00a4
4e GPIO[33] configure gpio_configure[33][12:8] 2600_00a9
4f GPIO[33] configure gpio_configure[33][7:0] 2600_00a8
50 GPIO[34] configure gpio_configure[34][12:8] 2600_00ad
51 GPIO[34] configure gpio_configure[34][7:0] 2600_00ac
52 GPIO[35] configure gpio_configure[35][12:8] 2600_00b1
53 GPIO[35] configure gpio_configure[35][7:0] 2600_00b0
54 GPIO[36] configure gpio_configure[36][12:8] 2600_00b5
55 GPIO[36] configure gpio_configure[36][7:0] 2600_00b4
56 GPIO[37] configure gpio_configure[37][12:8] 2600_00b9
57 GPIO[37] configure gpio_configure[37][7:0] 2600_00b8
58 GPIO data mgmt_gpio_in[37:32] 2600_0010
59 GPIO data mgmt_gpio_in[31:24] 2600_000f
5a GPIO data mgmt_gpio_in[23:16] 2600_000e
5b GPIO data mgmt_gpio_in[15:8] 2600_000d
5c GPIO data mgmt_gpio_in[7:0] 2600_000c
5d Power control pwr_ctrl_out[3:0] 2600_0004
5e GPIO control serial_resetn/clock/data 2600_0000
14 SRAM read-only control TBD TBD
15 SRAM read-only address TBD TBD
16 SRAM read-only data TBD TBD
17 SRAM read-only data TBD TBD
18 SRAM read-only data TBD TBD
19 SRAM read-only data TBD TBD
1a Power monitor usr1/2_vcc/vdd_pwrgood 2620_0000
1b Output redirect clk1/clk2/trap_output_dest 2620_0004
1c Input redirect irq_8/7_inputsrc 2620_000c
1d GPIO[0] configure gpio_configure[0][12:8] 2600_0025
1e GPIO[0] configure gpio_configure[0][7:0] 2600_0024
1f GPIO[1] configure gpio_configure[1][12:8] 2600_0029
20 GPIO[1] configure gpio_configure[1][7:0] 2600_0028
21 GPIO[2] configure gpio_configure[2][12:8] 2600_002d
22 GPIO[2] configure gpio_configure[2][7:0] 2600_002c
23 GPIO[3] configure gpio_configure[3][12:8] 2600_0031
24 GPIO[3] configure gpio_configure[3][7:0] 2600_0030
25 GPIO[4] configure gpio_configure[4][12:8] 2600_0035
26 GPIO[4] configure gpio_configure[4][7:0] 2600_0034
27 GPIO[5] configure gpio_configure[5][12:8] 2600_0039
28 GPIO[5] configure gpio_configure[5][7:0] 2600_0038
29 GPIO[6] configure gpio_configure[6][12:8] 2600_003d
2a GPIO[6] configure gpio_configure[6][7:0] 2600_003c
2b GPIO[7] configure gpio_configure[7][12:8] 2600_0041
2c GPIO[7] configure gpio_configure[7][7:0] 2600_0040
2d GPIO[8] configure gpio_configure[8][12:8] 2600_0045
2e GPIO[8] configure gpio_configure[8][7:0] 2600_0044
2f GPIO[9] configure gpio_configure[9][12:8] 2600_0049
30 GPIO[9] configure gpio_configure[9][7:0] 2600_0048
31 GPIO[10] configure gpio_configure[10][12:8] 2600_004d
32 GPIO[10] configure gpio_configure[10][7:0] 2600_004c
33 GPIO[11] configure gpio_configure[11][12:8] 2600_0051
34 GPIO[11] configure gpio_configure[11][7:0] 2600_0050
35 GPIO[12] configure gpio_configure[12][12:8] 2600_0055
36 GPIO[12] configure gpio_configure[12][7:0] 2600_0054
37 GPIO[13] configure gpio_configure[13][12:8] 2600_0059
38 GPIO[13] configure gpio_configure[13][7:0] 2600_0058
39 GPIO[14] configure gpio_configure[14][12:8] 2600_005d
3a GPIO[14] configure gpio_configure[14][7:0] 2600_005c
3b GPIO[15] configure gpio_configure[15][12:8] 2600_0061
3c GPIO[15] configure gpio_configure[15][7:0] 2600_0060
3d GPIO[16] configure gpio_configure[16][12:8] 2600_0065
3e GPIO[16] configure gpio_configure[16][7:0] 2600_0064
3f GPIO[17] configure gpio_configure[17][12:8] 2600_0069
40 GPIO[17] configure gpio_configure[17][7:0] 2600_0068
41 GPIO[18] configure gpio_configure[18][12:8] 2600_006d
42 GPIO[18] configure gpio_configure[18][7:0] 2600_006c
43 GPIO[19] configure gpio_configure[19][12:8] 2600_0071
44 GPIO[19] configure gpio_configure[19][7:0] 2600_0070
45 GPIO[20] configure gpio_configure[20][12:8] 2600_0075
46 GPIO[20] configure gpio_configure[20][7:0] 2600_0074
47 GPIO[21] configure gpio_configure[21][12:8] 2600_0079
48 GPIO[21] configure gpio_configure[21][7:0] 2600_0078
49 GPIO[22] configure gpio_configure[22][12:8] 2600_007d
4a GPIO[22] configure gpio_configure[22][7:0] 2600_007c
4b GPIO[23] configure gpio_configure[23][12:8] 2600_0081
4c GPIO[23] configure gpio_configure[23][7:0] 2600_0080
4d GPIO[24] configure gpio_configure[24][12:8] 2600_0085
4e GPIO[24] configure gpio_configure[24][7:0] 2600_0084
4f GPIO[25] configure gpio_configure[25][12:8] 2600_0089
50 GPIO[25] configure gpio_configure[25][7:0] 2600_0088
51 GPIO[26] configure gpio_configure[26][12:8] 2600_008d
52 GPIO[26] configure gpio_configure[26][7:0] 2600_008c
53 GPIO[27] configure gpio_configure[27][12:8] 2600_0091
54 GPIO[27] configure gpio_configure[27][7:0] 2600_0090
55 GPIO[28] configure gpio_configure[28][12:8] 2600_0095
56 GPIO[28] configure gpio_configure[28][7:0] 2600_0094
57 GPIO[29] configure gpio_configure[29][12:8] 2600_0099
58 GPIO[29] configure gpio_configure[29][7:0] 2600_0098
59 GPIO[30] configure gpio_configure[30][12:8] 2600_009d
5a GPIO[30] configure gpio_configure[30][7:0] 2600_009c
5b GPIO[31] configure gpio_configure[31][12:8] 2600_00a1
5c GPIO[31] configure gpio_configure[31][7:0] 2600_00a0
5d GPIO[32] configure gpio_configure[32][12:8] 2600_00a5
5e GPIO[32] configure gpio_configure[32][7:0] 2600_00a4
5f GPIO[33] configure gpio_configure[33][12:8] 2600_00a9
60 GPIO[33] configure gpio_configure[33][7:0] 2600_00a8
61 GPIO[34] configure gpio_configure[34][12:8] 2600_00ad
62 GPIO[34] configure gpio_configure[34][7:0] 2600_00ac
63 GPIO[35] configure gpio_configure[35][12:8] 2600_00b1
64 GPIO[35] configure gpio_configure[35][7:0] 2600_00b0
65 GPIO[36] configure gpio_configure[36][12:8] 2600_00b5
66 GPIO[36] configure gpio_configure[36][7:0] 2600_00b4
67 GPIO[37] configure gpio_configure[37][12:8] 2600_00b9
68 GPIO[37] configure gpio_configure[37][7:0] 2600_00b8
69 GPIO data mgmt_gpio_in[37:32] 2600_0010
6a GPIO data mgmt_gpio_in[31:24] 2600_000f
6b GPIO data mgmt_gpio_in[23:16] 2600_000e
6c GPIO data mgmt_gpio_in[15:8] 2600_000d
6d GPIO data mgmt_gpio_in[7:0] 2600_000c
6e Power control pwr_ctrl_out[3:0] 2600_0004
5f PLL enables pll_dco_ena, pll_ena 2610_000c
60 PLL bypass pll_bypass 2610_0010
61 IRQ irq 2610_0014
62 Reset reset 2610_0018
63 PLL trim pll_trim[31:24] 2610_001f
64 PLL trim pll_trim[23:16] 2610_001e
65 PLL trim pll_trim[15:8] 2610_001d
66 PLL trim pll_trim[7:0] 2610_001c
67 PLL source pll90_sel[2:0], pll_sel[2:0] 2610_0020
68 PLL divider pll_div[4:0] 2610_0024
----------------------------------------------------------------------------------

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 = gpio_mgmt
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,52 @@
/*
* 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"
// --------------------------------------------------------
/*
* Management SoC GPIO Pin Test
* Tests writing to the GPIO pin.
*/
void main()
{
int i;
reg_gpio_data = 0;
reg_gpio_ena = 0;
reg_gpio_pu = 0;
reg_gpio_pd = 0;
for (i = 0; i < 10; i++) {
/* Fast blink for simulation */
reg_gpio_data = 1;
reg_gpio_data = 0;
}
while (1) {
/* Slow blink for demonstration board */
for (i = 0; i < 30000; i++) {
reg_gpio_data = 1;
}
for (i = 0; i < 30000; i++) {
reg_gpio_data = 0;
}
}
}

View File

@ -0,0 +1,200 @@
`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 gpio_mgmt_tb;
reg clock;
reg power1;
reg power2;
always #10 clock <= (clock === 1'b0);
initial begin
clock <= 0;
end
initial begin
$dumpfile("gpio_mgmt.vcd");
$dumpvars(0, gpio_mgmt_tb);
// Repeat cycles of 1000 clock edges as needed to complete testbench
repeat (25) begin
repeat (1000) @(posedge clock);
$display("+1000 cycles");
end
$display("%c[1;31m",27);
`ifdef GL
$display ("Monitor: Timeout, Test Mgmt GPIO (GL) Failed");
`else
$display ("Monitor: Timeout, Test Mgmt GPIO (RTL) Failed");
`endif
$display("%c[0m",27);
$finish;
end
wire [37:0] mprj_io; // Most of these are no-connects
wire [15:0] checkbits;
reg [7:0] checkbits_lo;
wire [7:0] checkbits_hi;
assign mprj_io[23:16] = checkbits_lo;
assign checkbits = mprj_io[31:16];
assign checkbits_hi = checkbits[15:8];
assign mprj_io[3] = 1'b1; // Force CSB high.
wire flash_csb;
wire flash_clk;
wire flash_io0;
wire flash_io1;
wire gpio;
reg RSTB;
// Monitor
initial begin
wait(gpio == 1'b1);
wait(gpio == 1'b0);
$display("Blink.");
wait(gpio == 1'b1);
wait(gpio == 1'b0);
$display("Blink.");
wait(gpio == 1'b1);
wait(gpio == 1'b0);
$display("Blink.");
wait(gpio == 1'b1);
wait(gpio == 1'b0);
$display("Blink.");
wait(gpio == 1'b1);
wait(gpio == 1'b0);
$display("Blink.");
wait(gpio == 1'b1);
wait(gpio == 1'b0);
$display("Blink.");
wait(gpio == 1'b1);
wait(gpio == 1'b0);
$display("Blink.");
wait(gpio == 1'b1);
wait(gpio == 1'b0);
$display("Blink.");
wait(gpio == 1'b1);
wait(gpio == 1'b0);
$display("Blink.");
wait(gpio == 1'b1);
wait(gpio == 1'b0);
`ifdef GL
$display("Monitor: Test Mgmt GPIO (GL) Passed");
`else
$display("Monitor: Test Mgmt GPIO (RTL) Passed");
`endif
#2000;
$finish;
end
initial begin
RSTB <= 1'b0;
#1000;
RSTB <= 1'b1; // Release reset
#2000;
end
initial begin // Power-up
power1 <= 1'b0;
power2 <= 1'b0;
#200;
power1 <= 1'b1;
#200;
power2 <= 1'b1;
end
always @(checkbits) begin
#1 $display("Mgmt GPIO state = %b (%d - %d)", checkbits,
checkbits_hi, checkbits_lo);
end
wire VDD3V3;
wire VDD1V8;
wire VSS;
assign VDD3V3 = power1;
assign VDD1V8 = power2;
assign VSS = 1'b0;
// These are the mappings of mprj_io GPIO pads that are set to
// specific functions on startup:
//
// JTAG = mgmt_gpio_io[0] (inout)
// SDO = mgmt_gpio_io[1] (output)
// SDI = mgmt_gpio_io[2] (input)
// CSB = mgmt_gpio_io[3] (input)
// SCK = mgmt_gpio_io[4] (input)
// ser_rx = mgmt_gpio_io[5] (input)
// ser_tx = mgmt_gpio_io[6] (output)
// irq = mgmt_gpio_io[7] (input)
caravel uut (
.vddio (VDD3V3),
.vssio (VSS),
.vdda (VDD3V3),
.vssa (VSS),
.vccd (VDD1V8),
.vssd (VSS),
.vdda1 (VDD3V3),
.vdda2 (VDD3V3),
.vssa1 (VSS),
.vssa2 (VSS),
.vccd1 (VDD1V8),
.vccd2 (VDD1V8),
.vssd1 (VSS),
.vssd2 (VSS),
.clock (clock),
.gpio (gpio),
.mprj_io (mprj_io),
.flash_csb(flash_csb),
.flash_clk(flash_clk),
.flash_io0(flash_io0),
.flash_io1(flash_io1),
.resetb (RSTB)
);
spiflash #(
.FILENAME("gpio_mgmt.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 = hkspi
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,92 @@
/*
* 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 interrupted only when the reset is applied
// through the SPI.
// Configure I/O: High 16 bits of user area used for a 16-bit
// word to write and be detected by the testbench verilog.
// Only serial Tx line is used in this testbench. It connects
// to mprj_io[6]. Since all lines of the chip are input or
// high impedence on startup, the I/O has to be configured
// for output
reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_6 = GPIO_MODE_MGMT_STD_OUTPUT;
// Apply configuration
reg_mprj_xfer = 1;
while (reg_mprj_xfer == 1);
// Start test
reg_mprj_datal = 0xa0000000;
// Set clock to 64 kbaud and enable the UART
reg_uart_clkdiv = 625;
reg_uart_enable = 1;
// Test message
print("\n");
print(" ____ _ ____ ____\n");
print(" | _ \\(_) ___ ___/ ___| ___ / ___|\n");
print(" | |_) | |/ __/ _ \\___ \\ / _ \\| |\n");
print(" | __/| | (_| (_) |__) | (_) | |___\n");
print(" |_| |_|\\___\\___/____/ \\___/ \\____|\n");
reg_mprj_datal = 0xab000000;
}

View File

@ -0,0 +1,431 @@
// 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 SPI testbench.
*/
`timescale 1 ns / 1 ps
`include "__uprj_netlists.v"
`include "caravel_netlists.v"
`include "spiflash.v"
`include "tbuart.v"
module hkspi_tb;
reg clock;
reg SDI, CSB, SCK, RSTB;
reg power1, power2;
wire gpio;
wire [15:0] checkbits;
wire [37:0] mprj_io;
wire uart_tx;
wire uart_rx;
wire flash_csb;
wire flash_clk;
wire flash_io0;
wire flash_io1;
wire flash_io2;
wire flash_io3;
wire SDO;
always #10 clock <= (clock === 1'b0);
initial begin
clock = 0;
end
initial begin // Power-up sequence
power1 <= 1'b0;
power2 <= 1'b0;
#200;
power1 <= 1'b1;
#200;
power2 <= 1'b1;
end
// The main testbench is here. Put the housekeeping SPI into
// pass-thru mode and read several bytes from the flash SPI.
// First define tasks for SPI functions
task start_csb;
begin
SCK <= 1'b0;
SDI <= 1'b0;
CSB <= 1'b0;
#50;
end
endtask
task end_csb;
begin
SCK <= 1'b0;
SDI <= 1'b0;
CSB <= 1'b1;
#50;
end
endtask
task write_byte;
input [7:0] odata;
begin
SCK <= 1'b0;
for (i=7; i >= 0; i--) begin
#50;
SDI <= odata[i];
#50;
SCK <= 1'b1;
#100;
SCK <= 1'b0;
end
end
endtask
task read_byte;
output [7:0] idata;
begin
SCK <= 1'b0;
SDI <= 1'b0;
for (i=7; i >= 0; i--) begin
#50;
idata[i] = SDO;
#50;
SCK <= 1'b1;
#100;
SCK <= 1'b0;
end
end
endtask
task read_write_byte
(input [7:0] odata,
output [7:0] idata);
begin
SCK <= 1'b0;
for (i=7; i >= 0; i--) begin
#50;
SDI <= odata[i];
idata[i] = SDO;
#50;
SCK <= 1'b1;
#100;
SCK <= 1'b0;
end
end
endtask
integer i;
// Now drive the digital signals on the housekeeping SPI
reg [7:0] tbdata;
initial begin
$dumpfile("hkspi.vcd");
$dumpvars(0, hkspi_tb);
CSB <= 1'b1;
SCK <= 1'b0;
SDI <= 1'b0;
RSTB <= 1'b0;
// Delay, then bring chip out of reset
#1000;
RSTB <= 1'b1;
#2000;
// First do a normal read from the housekeeping SPI to
// make sure the housekeeping SPI works.
start_csb();
write_byte(8'h40); // Read stream command
write_byte(8'h03); // Address (register 3 = product ID)
read_byte(tbdata);
end_csb();
#10;
$display("Read data = 0x%02x (should be 0x11)", tbdata);
// Toggle external reset
start_csb();
write_byte(8'h80); // Write stream command
write_byte(8'h0b); // Address (register 7 = external reset)
write_byte(8'h01); // Data = 0x01 (apply external reset)
end_csb();
start_csb();
write_byte(8'h80); // Write stream command
write_byte(8'h0b); // Address (register 7 = external reset)
write_byte(8'h00); // Data = 0x00 (release external reset)
end_csb();
// Read all registers (0 to 18)
start_csb();
write_byte(8'h40); // Read stream command
write_byte(8'h00); // Address (register 3 = product ID)
read_byte(tbdata);
$display("Read register 0 = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 1 = 0x%02x (should be 0x04)", tbdata);
if(tbdata !== 8'h04) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 2 = 0x%02x (should be 0x56)", tbdata);
if(tbdata !== 8'h56) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed, %02x", tbdata); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed, %02x", tbdata); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 3 = 0x%02x (should be 0x11)", tbdata);
if(tbdata !== 8'h11) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed, %02x", tbdata); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed, %02x", tbdata); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 4 = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 5 = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 6 = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 7 = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 8 = 0x%02x (should be 0x02)", tbdata);
if(tbdata !== 8'h02) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 9 = 0x%02x (should be 0x01)", tbdata);
if(tbdata !== 8'h01) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 10 = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 11 = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 12 = 0x%02x (should be 0x00)", tbdata);
if(tbdata !== 8'h00) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 13 = 0x%02x (should be 0xff)", tbdata);
if(tbdata !== 8'hff) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 14 = 0x%02x (should be 0xef)", tbdata);
if(tbdata !== 8'hef) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 15 = 0x%02x (should be 0xff)", tbdata);
if(tbdata !== 8'hff) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 16 = 0x%02x (should be 0x03)", tbdata);
if(tbdata !== 8'h03) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 17 = 0x%02x (should be 0x12)", tbdata);
if(tbdata !== 8'h12) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
read_byte(tbdata);
$display("Read register 18 = 0x%02x (should be 0x04)", tbdata);
if(tbdata !== 8'h04) begin
`ifdef GL
$display("Monitor: Test HK SPI (GL) Failed"); $finish;
`else
$display("Monitor: Test HK SPI (RTL) Failed"); $finish;
`endif
end
end_csb();
`ifdef GL
$display("Monitor: Test HK SPI (GL) Passed");
`else
$display("Monitor: Test HK SPI (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];
caravel uut (
.vddio (VDD3V3),
.vssio (VSS),
.vdda (VDD3V3),
.vssa (VSS),
.vccd (VDD1V8),
.vssd (VSS),
.vdda1 (VDD3V3),
.vdda2 (VDD3V3),
.vssa1 (VSS),
.vssa2 (VSS),
.vccd1 (VDD1V8),
.vccd2 (VDD1V8),
.vssd1 (VSS),
.vssd2 (VSS),
.clock (clock),
.gpio (gpio),
.mprj_io (mprj_io),
.flash_csb(flash_csb),
.flash_clk(flash_clk),
.flash_io0(flash_io0),
.flash_io1(flash_io1),
.resetb (RSTB)
);
spiflash #(
.FILENAME("hkspi.hex")
) spiflash (
.csb(flash_csb),
.clk(flash_clk),
.io0(flash_io0),
.io1(flash_io1),
.io2(), // not used
.io3() // not used
);
tbuart tbuart (
.ser_rx(uart_tx)
);
endmodule
`default_nettype wire

View File

@ -0,0 +1,93 @@
`default_nettype none
/*
* SPDX-FileCopyrightText: 2017 Clifford Wolf
*
* PicoSoC - A simple example SoC using PicoRV32
*
* Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
*
* 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
/* tbuart --- mimic an external UART display, operating at 9600 baud */
/* and accepting ASCII characters for display. */
/* To do: Match a known UART 3.3V 16x2 LCD display. However, it */
/* should be possible on a testing system to interface to the UART */
/* pins on a Raspberry Pi, also running at 3.3V. */
module tbuart (
input ser_rx
);
reg [3:0] recv_state;
reg [2:0] recv_divcnt;
reg [7:0] recv_pattern;
reg [8*50-1:0] recv_buf_data; // 50 characters. Increase as needed for tests.
reg clk;
initial begin
clk <= 1'b0;
recv_state <= 0;
recv_divcnt <= 0;
recv_pattern <= 0;
recv_buf_data <= 0;
end
// NOTE: Running at 3.0us clock period @ 5 clocks per bit = 15.0us per
// bit ~= 64 kbaud. Not tuned to any particular UART. Most run at
// 9600 baud default and will bounce up to higher baud rates when
// passed specific command words.
always #1500 clk <= (clk === 1'b0);
always @(posedge clk) begin
recv_divcnt <= recv_divcnt + 1;
case (recv_state)
0: begin
if (!ser_rx)
recv_state <= 1;
recv_divcnt <= 0;
end
1: begin
if (2*recv_divcnt > 3'd3) begin
recv_state <= 2;
recv_divcnt <= 0;
end
end
10: begin
if (recv_divcnt > 3'd3) begin
// 0x0a = '\n'
if (recv_pattern == 8'h0a) begin
$display("output: %s", recv_buf_data);
end else begin
recv_buf_data <= {recv_buf_data, recv_pattern};
end
recv_state <= 0;
end
end
default: begin
if (recv_divcnt > 3'd3) begin
recv_pattern <= {ser_rx, recv_pattern[7:1]};
recv_state <= recv_state + 1;
recv_divcnt <= 0;
end
end
endcase
end
endmodule

File diff suppressed because it is too large Load Diff