Skip to content

Commit e64bf92

Browse files
committed
Adding a Verilog example using PicoSoC
Signed-off-by: gatecat <[email protected]>
1 parent 9427f34 commit e64bf92

File tree

18 files changed

+1166
-2
lines changed

18 files changed

+1166
-2
lines changed

.github/workflows/main.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ jobs:
2323
runs-on: ubuntu-latest
2424
strategy:
2525
matrix:
26-
design: ['mcu_soc', 'minimal']
26+
design: ['mcu_soc', 'minimal', 'picosoc_verilog']
2727
steps:
2828
- name: Check out source code
2929
uses: actions/checkout@v4
30+
with:
31+
submodules: true
3032

3133
- uses: actions/setup-python@v4
3234
with:
@@ -56,10 +58,12 @@ jobs:
5658
runs-on: ubuntu-latest
5759
strategy:
5860
matrix:
59-
design: ['mcu_soc', 'minimal']
61+
design: ['mcu_soc', 'minimal', 'picosoc_verilog']
6062
steps:
6163
- name: Check out source code
6264
uses: actions/checkout@v4
65+
with:
66+
submodules: true
6367

6468
- name: Set up PDM
6569
uses: pdm-project/setup-pdm@v4

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ __pycache__/
1919
/build
2020
/mcu_soc/build
2121
/minimal/build
22+
/picosoc_verilog/build
2223

2324
# testbenches
2425
*.vcd

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "picosoc_verilog/design/picorv32"]
2+
path = picosoc_verilog/design/picorv32
3+
url = https://github.com/YosysHQ/picorv32

picosoc_verilog/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# PicoSoC (Verilog)
2+
3+
This example design shows how an existing Verilog design (picosoc) can be wrapped in a minimal layer of Amaranth and submitted to the ChipFlow platform.
4+

picosoc_verilog/chipflow.toml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[chipflow]
2+
project_name = "chipflow-examples-picosoc"
3+
4+
[chipflow.top]
5+
soc = "design.design:MySoC"
6+
7+
[chipflow.steps]
8+
software = "design.steps.software:MySoftwareStep"
9+
10+
[chipflow.clocks]
11+
default = 'sys_clk'
12+
13+
[chipflow.resets]
14+
default = 'sys_rst_n'
15+
16+
[chipflow.silicon]
17+
process = "ihp_sg13g2"
18+
package = "pga144"
19+
20+
[chipflow.silicon.pads]
21+
# System
22+
sys_clk = { type = "clock", loc = "114" }
23+
sys_rst_n = { type = "reset", loc = "115" }
24+
25+
[chipflow.silicon.power]
26+
dvss0 = { type = "power", loc = "1" }
27+
dvdd0 = { type = "ground", loc = "9" }
28+
vss0 = { type = "power", loc = "17" }
29+
vdd0 = { type = "ground", loc = "25" }
30+
dvss1 = { type = "power", loc = "33" }
31+
dvdd1 = { type = "ground", loc = "41" }
32+
vss1 = { type = "power", loc = "49" }
33+
vdd1 = { type = "ground", loc = "57" }
34+
dvss2 = { type = "power", loc = "65" }
35+
dvdd2 = { type = "ground", loc = "73" }
36+
vss2 = { type = "power", loc = "81" }
37+
vdd2 = { type = "ground", loc = "89" }
38+
dvss3 = { type = "power", loc = "97" }
39+
dvdd3 = { type = "ground", loc = "105" }
40+
vss3 = { type = "power", loc = "113" }
41+
vdd3 = { type = "ground", loc = "121" }
42+
dvss4 = { type = "power", loc = "129" }
43+
dvdd4 = { type = "ground", loc = "137" }

picosoc_verilog/design/design.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import os
2+
3+
from chipflow_lib.platforms.sim import SimPlatform
4+
5+
from amaranth import Module, Instance, ClockSignal, ResetSignal
6+
from amaranth.lib import wiring
7+
from amaranth.lib.wiring import In, Out, flipped, connect
8+
9+
from chipflow_lib.platforms import InputIOSignature, OutputIOSignature, BidirIOSignature
10+
11+
__all__ = ["MySoC"]
12+
13+
# Define signatures for the top level interface types
14+
class _QSPISignature(wiring.Signature):
15+
def __init__(self):
16+
super().__init__({
17+
"clk": Out(OutputIOSignature(1)),
18+
"csn": Out(OutputIOSignature(1)),
19+
"d": Out(BidirIOSignature(4, all_have_oe=True)),
20+
})
21+
22+
class _UARTSignature(wiring.Signature):
23+
def __init__(self):
24+
super().__init__({
25+
"tx": Out(OutputIOSignature(1)),
26+
"rx": Out(InputIOSignature(1)),
27+
})
28+
29+
class _GPIOSignature(wiring.Signature):
30+
def __init__(self, pin_count=1):
31+
if pin_count > 32:
32+
raise ValueError(f"Pin pin_count must be lesser than or equal to 32, not {pin_count}")
33+
super().__init__({
34+
"gpio": Out(BidirIOSignature(pin_count, all_have_oe=True))
35+
})
36+
37+
class MySoC(wiring.Component):
38+
def __init__(self):
39+
# Top level interfaces
40+
41+
super().__init__({
42+
"flash": Out(_QSPISignature()),
43+
"uart_0": Out(_UARTSignature()),
44+
"gpio_0": Out(_GPIOSignature(pin_count=8)),
45+
})
46+
47+
def elaborate(self, platform):
48+
m = Module()
49+
50+
base = os.path.dirname(__file__)
51+
52+
verilog_sources = [
53+
f"{base}/picosoc_asic_top.v",
54+
f"{base}/picorv32/picosoc/spimemio.v",
55+
f"{base}/picorv32/picosoc/simpleuart.v",
56+
f"{base}/picorv32/picosoc/picosoc.v",
57+
f"{base}/picorv32/picorv32.v",
58+
]
59+
60+
for verilog_file in verilog_sources:
61+
with open(verilog_file, 'r') as f:
62+
platform.add_file(verilog_file, f)
63+
64+
m.submodules.soc = soc = Instance("picosoc_asic_top",
65+
# Clock and reset
66+
i_clk=ClockSignal(),
67+
i_resetn=~ResetSignal(),
68+
69+
# UART
70+
o_ser_tx=self.uart_0.tx.o,
71+
i_ser_rx=self.uart_0.rx.i,
72+
73+
# SPI flash
74+
o_flash_csb=self.flash.csn.o,
75+
o_flash_clk=self.flash.clk.o,
76+
77+
o_flash_io0_oe=self.flash.d.oe[0],
78+
o_flash_io1_oe=self.flash.d.oe[1],
79+
o_flash_io2_oe=self.flash.d.oe[2],
80+
o_flash_io3_oe=self.flash.d.oe[3],
81+
82+
o_flash_io0_do=self.flash.d.o[0],
83+
o_flash_io1_do=self.flash.d.o[1],
84+
o_flash_io2_do=self.flash.d.o[2],
85+
o_flash_io3_do=self.flash.d.o[3],
86+
87+
i_flash_io0_di=self.flash.d.i[0],
88+
i_flash_io1_di=self.flash.d.i[1],
89+
i_flash_io2_di=self.flash.d.i[2],
90+
i_flash_io3_di=self.flash.d.i[3],
91+
92+
# LEDs
93+
o_leds=self.gpio_0.gpio.o
94+
)
95+
96+
# Hardwire GPIO to output enabled
97+
m.d.comb += self.gpio_0.gpio.oe.eq(0xFF)
98+
99+
return m

picosoc_verilog/design/picorv32

Submodule picorv32 added at 87c89ac
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* PicoSoC - A simple example SoC using PicoRV32
3+
*
4+
* Copyright (C) 2017 Claire Xenia Wolf <[email protected]>
5+
* Copyright (C) 2025 Myrtle Shah <[email protected]>
6+
*
7+
* Permission to use, copy, modify, and/or distribute this software for any
8+
* purpose with or without fee is hereby granted, provided that the above
9+
* copyright notice and this permission notice appear in all copies.
10+
*
11+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18+
*
19+
*/
20+
21+
`define PICOSOC_MEM picosoc_asic_mem
22+
23+
module picosoc_asic_top (
24+
input clk,
25+
input resetn,
26+
27+
output ser_tx,
28+
input ser_rx,
29+
30+
output [7:0] leds,
31+
32+
output flash_csb,
33+
output flash_clk,
34+
35+
output flash_io0_oe,
36+
output flash_io1_oe,
37+
output flash_io2_oe,
38+
output flash_io3_oe,
39+
40+
output flash_io0_do,
41+
output flash_io1_do,
42+
output flash_io2_do,
43+
output flash_io3_do,
44+
45+
input flash_io0_di,
46+
input flash_io1_di,
47+
input flash_io2_di,
48+
input flash_io3_di
49+
);
50+
51+
wire iomem_valid;
52+
reg iomem_ready;
53+
wire [3:0] iomem_wstrb;
54+
wire [31:0] iomem_addr;
55+
wire [31:0] iomem_wdata;
56+
reg [31:0] iomem_rdata;
57+
58+
reg [31:0] gpio;
59+
assign leds = gpio;
60+
61+
always @(posedge clk) begin
62+
if (!resetn) begin
63+
gpio <= 0;
64+
end else begin
65+
iomem_ready <= 0;
66+
if (iomem_valid && !iomem_ready && iomem_addr[31:24] == 8'h 03) begin
67+
iomem_ready <= 1;
68+
iomem_rdata <= gpio;
69+
if (iomem_wstrb[0]) gpio[ 7: 0] <= iomem_wdata[ 7: 0];
70+
if (iomem_wstrb[1]) gpio[15: 8] <= iomem_wdata[15: 8];
71+
if (iomem_wstrb[2]) gpio[23:16] <= iomem_wdata[23:16];
72+
if (iomem_wstrb[3]) gpio[31:24] <= iomem_wdata[31:24];
73+
end
74+
end
75+
end
76+
77+
picosoc soc (
78+
.clk (clk ),
79+
.resetn (resetn ),
80+
81+
.ser_tx (ser_tx ),
82+
.ser_rx (ser_rx ),
83+
84+
.flash_csb (flash_csb ),
85+
.flash_clk (flash_clk ),
86+
87+
.flash_io0_oe (flash_io0_oe),
88+
.flash_io1_oe (flash_io1_oe),
89+
.flash_io2_oe (flash_io2_oe),
90+
.flash_io3_oe (flash_io3_oe),
91+
92+
.flash_io0_do (flash_io0_do),
93+
.flash_io1_do (flash_io1_do),
94+
.flash_io2_do (flash_io2_do),
95+
.flash_io3_do (flash_io3_do),
96+
97+
.flash_io0_di (flash_io0_di),
98+
.flash_io1_di (flash_io1_di),
99+
.flash_io2_di (flash_io2_di),
100+
.flash_io3_di (flash_io3_di),
101+
102+
.irq_5 (1'b0 ),
103+
.irq_6 (1'b0 ),
104+
.irq_7 (1'b0 ),
105+
106+
.iomem_valid (iomem_valid ),
107+
.iomem_ready (iomem_ready ),
108+
.iomem_wstrb (iomem_wstrb ),
109+
.iomem_addr (iomem_addr ),
110+
.iomem_wdata (iomem_wdata ),
111+
.iomem_rdata (iomem_rdata )
112+
);
113+
endmodule
114+
115+
module picosoc_asic_mem #(
116+
parameter integer WORDS = 256
117+
) (
118+
input clk,
119+
input [3:0] wen,
120+
input [21:0] addr,
121+
input [31:0] wdata,
122+
output reg [31:0] rdata
123+
);
124+
reg [31:0] mem [0:WORDS-1];
125+
126+
always @(posedge clk) begin
127+
if (wen == 4'b0)
128+
rdata <= mem[addr];
129+
if (wen[0]) mem[addr][ 7: 0] <= wdata[ 7: 0];
130+
if (wen[1]) mem[addr][15: 8] <= wdata[15: 8];
131+
if (wen[2]) mem[addr][23:16] <= wdata[23:16];
132+
if (wen[3]) mem[addr][31:24] <= wdata[31:24];
133+
end
134+
endmodule
135+

picosoc_verilog/design/sim/main.cc

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#undef NDEBUG
2+
3+
#include <cxxrtl/cxxrtl.h>
4+
#include <cxxrtl/cxxrtl_server.h>
5+
#include "sim_soc.h"
6+
#include "models.h"
7+
8+
#include <fstream>
9+
#include <filesystem>
10+
11+
using namespace cxxrtl::time_literals;
12+
using namespace cxxrtl_design;
13+
14+
int main(int argc, char **argv) {
15+
p_sim__top top;
16+
17+
spiflash_model flash("flash", top.p_io_24_flash__clk_24_o, top.p_io_24_flash__csn_24_o,
18+
top.p_io_24_flash__d_24_o, top.p_io_24_flash__d_24_oe, top.p_io_24_flash__d_24_i);
19+
20+
uart_model uart_0("uart_0", top.p_io_24_uart__0__tx_24_o, top.p_io_24_uart__0__rx_24_i);
21+
22+
gpio_model gpio_0("gpio_0", top.p_io_24_gpio__0__gpio_24_o, top.p_io_24_gpio__0__gpio_24_oe, top.p_io_24_gpio__0__gpio_24_i);
23+
24+
cxxrtl::agent agent(cxxrtl::spool("spool.bin"), top);
25+
if (getenv("DEBUG")) // can also be done when a condition is violated, etc
26+
std::cerr << "Waiting for debugger on " << agent.start_debugging() << std::endl;
27+
28+
open_event_log(BUILD_DIR "/sim/events.json");
29+
open_input_commands(PROJECT_ROOT "/design/tests/input.json");
30+
31+
unsigned timestamp = 0;
32+
auto tick = [&]() {
33+
// agent.print(stringf("timestamp %d\n", timestamp), CXXRTL_LOCATION);
34+
35+
flash.step(timestamp);
36+
uart_0.step(timestamp);
37+
38+
gpio_0.step(timestamp);
39+
40+
top.p_io_24_sys__clk_24_i.set(false);
41+
agent.step();
42+
agent.advance(1_us);
43+
++timestamp;
44+
45+
top.p_io_24_sys__clk_24_i.set(true);
46+
agent.step();
47+
agent.advance(1_us);
48+
++timestamp;
49+
50+
// if (timestamp == 10)
51+
// agent.breakpoint(CXXRTL_LOCATION);
52+
};
53+
54+
flash.load_data("../software/software.bin", 0x00100000U);
55+
agent.step();
56+
agent.advance(1_us);
57+
58+
top.p_io_24_sys__rst__n_24_i.set(false);
59+
tick();
60+
61+
top.p_io_24_sys__rst__n_24_i.set(true);
62+
for (int i = 0; i < 1000000; i++)
63+
tick();
64+
65+
close_event_log();
66+
return 0;
67+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.o
2+
*.elf
3+
*.bin
4+
generated/

0 commit comments

Comments
 (0)