From 3ccfa11b78257754f0b7d6298de65259881126aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Sza=C5=82kowski?= Date: Thu, 17 Oct 2024 13:54:03 +0200 Subject: [PATCH] Create example designs for the new IR --- docs/source/developers_guide/ir-examples.md | 62 ++++++++++++ docs/source/index.md | 1 + examples/ir_examples/README.md | 8 ++ examples/ir_examples/hierarchical/Makefile | 13 +++ examples/ir_examples/hierarchical/design.yaml | 98 +++++++++++++++++++ .../ir_examples/hierarchical/ips/adder.yaml | 11 +++ .../ir_examples/hierarchical/ips/d_ff.yaml | 12 +++ .../hierarchical/ips/debouncer.yaml | 11 +++ examples/ir_examples/interconnect/Makefile | 13 +++ examples/ir_examples/interconnect/design.yaml | 63 ++++++++++++ .../ir_examples/interconnect/ips/cpu.yaml | 23 +++++ .../ir_examples/interconnect/ips/dsp.yaml | 27 +++++ .../ir_examples/interconnect/ips/mem.yaml | 27 +++++ .../interconnect/ips/wb_passthrough.yaml | 38 +++++++ examples/ir_examples/interface/Makefile | 13 +++ examples/ir_examples/interface/design.yaml | 26 +++++ .../ir_examples/interface/ips/receiver.yaml | 17 ++++ .../ir_examples/interface/ips/streamer.yaml | 20 ++++ examples/ir_examples/simple/Makefile | 13 +++ examples/ir_examples/simple/design.yaml | 36 +++++++ examples/ir_examples/simple/ips/2mux.yaml | 13 +++ examples/ir_examples/simple/ips/lfsr_gen.yaml | 12 +++ noxfile.py | 9 +- 23 files changed, 562 insertions(+), 4 deletions(-) create mode 100644 docs/source/developers_guide/ir-examples.md create mode 100644 examples/ir_examples/README.md create mode 100644 examples/ir_examples/hierarchical/Makefile create mode 100644 examples/ir_examples/hierarchical/design.yaml create mode 100644 examples/ir_examples/hierarchical/ips/adder.yaml create mode 100644 examples/ir_examples/hierarchical/ips/d_ff.yaml create mode 100644 examples/ir_examples/hierarchical/ips/debouncer.yaml create mode 100644 examples/ir_examples/interconnect/Makefile create mode 100644 examples/ir_examples/interconnect/design.yaml create mode 100644 examples/ir_examples/interconnect/ips/cpu.yaml create mode 100644 examples/ir_examples/interconnect/ips/dsp.yaml create mode 100644 examples/ir_examples/interconnect/ips/mem.yaml create mode 100644 examples/ir_examples/interconnect/ips/wb_passthrough.yaml create mode 100644 examples/ir_examples/interface/Makefile create mode 100644 examples/ir_examples/interface/design.yaml create mode 100644 examples/ir_examples/interface/ips/receiver.yaml create mode 100644 examples/ir_examples/interface/ips/streamer.yaml create mode 100644 examples/ir_examples/simple/Makefile create mode 100644 examples/ir_examples/simple/design.yaml create mode 100644 examples/ir_examples/simple/ips/2mux.yaml create mode 100644 examples/ir_examples/simple/ips/lfsr_gen.yaml diff --git a/docs/source/developers_guide/ir-examples.md b/docs/source/developers_guide/ir-examples.md new file mode 100644 index 0000000..6b8a594 --- /dev/null +++ b/docs/source/developers_guide/ir-examples.md @@ -0,0 +1,62 @@ +# Examples for Internal Representation + +There are four examples in `examples/ir_examples` showcasing specific features of Topwrap which we want to take into consideration while creating the new internal representation. + +## Simple + +This is a simple non-hierarchical example that uses two IPs. Inside, there are two LFSR RNGs constantly generating pseudorandom numbers on their outputs. They are both connected to a multiplexer that selects which generator's output should be passed to the `rnd_bit` external output port. The specific generator is selected using the `sel_gen` input port. + +This example features: +- IP core parameters +- variable width ports + +```{kpm_iframe} +:dataflow: ../../build/kpm_jsons/data_ir_examples_simple.json +:spec: ../../build/kpm_jsons/spec_ir_examples_simple.json +``` + +## Interface + +This is another simple example using two IPs, this time with an interface. The design consists of a streamer IP and a receiver IP. They both are connected using the AXI4Stream interface. The receiver then passes the data to an external inout port. + +This example features: +- usage of interface ports +- port slicing +- constant value connected to a port +- an Inout port + +```{kpm_iframe} +:dataflow: ../../build/kpm_jsons/data_ir_examples_interface.json +:spec: ../../build/kpm_jsons/spec_ir_examples_interface.json +``` + +## Hierarchical + +This is an example of a hierarchical design. The top-level features standard external ports `clk` and `rst`, a `btn` input that represents an input from a physical button, and `disp0..2` outputs that go to an imaginary 3-wire-controlled display. All these ports are connected to a processing hierarchy `proc`. Inside this hierarchy we can see the `btn` input going into a "debouncer" IP, its output going into a 4-bit counter, the counter's sum arriving into an encoder as the input number, and the display outputs from the encoder further lifted to the parent level. The encoder itself is a hierarchy, though an empty one with only the ports defined. The 4-bit counter is also a hierarchy that can be further explored. It consists of a variable width adder IP and a flip-flop register IP. + +This example features: +- hierarchies of more than one depth + +```{kpm_iframe} +:dataflow: ../../build/kpm_jsons/data_ir_examples_hierarchical.json +:spec: ../../build/kpm_jsons/spec_ir_examples_hierarchical.json +``` + +## Interconnect + +This is an example of our interconnect generation feature. The design features 3 IP cores: a memory core (`ips/mem.yaml`), a digital signal processor (`ips/dsp.yaml`) and a CPU (`ips/cpu.yaml`). All of them are connected to a wishbone interconnect where both the CPU and an external interface `ext_manager` act as managers and drive the bus. DSP and MEM are subordinates, one available at address 0x0, the other at 0x10000. + +Note that while this specific example uses a "wishbone_roundrobin" interconnect, we still aim to support other types of them in the future. +Each one will have its own schema for the "params" section so make sure not to hardcode the parameters' keys or values. + +This example features: +- usage of interface ports +- interconnect usage + +:::{note} +No KPM example for this one since interconnects are still irrepresentable in it. +::: + +## Other + +Something that was not taken into account previously, because we don't support it yet, and it's impossible to represent in either format, is a feature/syntax that would allow us to dynamically change the collection of ports/interfaces an IP/hierarchy has. Similarly to how we can control the width of a port using a parameter (like in the "simple" example). diff --git a/docs/source/index.md b/docs/source/index.md index 83ecd75..36db998 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -33,4 +33,5 @@ developers_guide/parsing developers_guide/examples developers_guide/future_enhancements developers_guide/inline_kpm_howto +developers_guide/ir-examples ``` diff --git a/examples/ir_examples/README.md b/examples/ir_examples/README.md new file mode 100644 index 0000000..9d000df --- /dev/null +++ b/examples/ir_examples/README.md @@ -0,0 +1,8 @@ +# Examples for internal representation + +These examples represent different feature sets that are important for us in Topwrap. +They are used to gather requirements for our internal data format based on features we want to support and on the syntax of other independent external formats like IP-XACT. + +More information about them is available in the documentation at https://antmicro.github.io/topwrap/developers_guide/ir-examples.md + +Copyright (c) 2024 [Antmicro](https://antmicro.com) diff --git a/examples/ir_examples/hierarchical/Makefile b/examples/ir_examples/hierarchical/Makefile new file mode 100644 index 0000000..b3ddc7a --- /dev/null +++ b/examples/ir_examples/hierarchical/Makefile @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +JSONS = kpm_spec.json kpm_dataflow.json + +all: $(JSONS) + +$(JSONS): + topwrap specification ips/*.yaml + topwrap dataflow -d design.yaml ips/*.yaml + +clean: + rm -f $(JSONS) diff --git a/examples/ir_examples/hierarchical/design.yaml b/examples/ir_examples/hierarchical/design.yaml new file mode 100644 index 0000000..c1ebc0c --- /dev/null +++ b/examples/ir_examples/hierarchical/design.yaml @@ -0,0 +1,98 @@ +design: + hierarchies: + proc: + design: + hierarchies: + 4-bit counter: + design: + parameters: + D-flipflop: + WIDTH: 4 + adder: + WIDTH: 4 + ports: + D-flipflop: + D: + - adder + - sum + Q: sum + clk: impulse + rst: rst + adder: + a: + - D-flipflop + - Q + b: impulse + external: + ports: + in: + - impulse + - rst + out: + - sum + ips: + D-flipflop: + file: ips/d_ff.yaml + adder: + file: ips/adder.yaml + encoder: + external: + ports: + in: + - number + - clk + out: + - enc0 + - enc1 + - enc2 + parameters: + debouncer: + GRACE: 1000 + ports: + 4-bit counter: + impulse: + - debouncer + - filtered_out + rst: rst + debouncer: + clk: clk + in: btn + encoder: + clk: clk + enc0: enc0 + enc1: enc1 + enc2: enc2 + number: + - 4-bit counter + - sum + external: + ports: + in: + - btn + - clk + - rst + out: + - enc0 + - enc1 + - enc2 + ips: + debouncer: + file: ips/debouncer.yaml + ports: + proc: + btn: btn + clk: clk + enc0: disp0 + enc1: disp1 + enc2: disp2 + rst: rst +external: + ports: + in: + - clk + - btn + - rst + out: + - disp0 + - disp1 + - disp2 diff --git a/examples/ir_examples/hierarchical/ips/adder.yaml b/examples/ir_examples/hierarchical/ips/adder.yaml new file mode 100644 index 0000000..2f2d53b --- /dev/null +++ b/examples/ir_examples/hierarchical/ips/adder.yaml @@ -0,0 +1,11 @@ +name: adder + +parameters: + WIDTH: 4 + +signals: + in: + - [a, WIDTH-1, 0] + - [b, WIDTH-1, 0] + out: + - [sum, WIDTH-1, 0] diff --git a/examples/ir_examples/hierarchical/ips/d_ff.yaml b/examples/ir_examples/hierarchical/ips/d_ff.yaml new file mode 100644 index 0000000..62976cc --- /dev/null +++ b/examples/ir_examples/hierarchical/ips/d_ff.yaml @@ -0,0 +1,12 @@ +name: D-flipflop + +parameters: + WIDTH: 4 + +signals: + in: + - clk + - rst + - [D, WIDTH-1, 0] + out: + - [Q, WIDTH-1, 0] diff --git a/examples/ir_examples/hierarchical/ips/debouncer.yaml b/examples/ir_examples/hierarchical/ips/debouncer.yaml new file mode 100644 index 0000000..8072c42 --- /dev/null +++ b/examples/ir_examples/hierarchical/ips/debouncer.yaml @@ -0,0 +1,11 @@ +name: debouncer + +parameters: + GRACE: 1000 + +signals: + in: + - clk + - in + out: + - filtered_out diff --git a/examples/ir_examples/interconnect/Makefile b/examples/ir_examples/interconnect/Makefile new file mode 100644 index 0000000..b3ddc7a --- /dev/null +++ b/examples/ir_examples/interconnect/Makefile @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +JSONS = kpm_spec.json kpm_dataflow.json + +all: $(JSONS) + +$(JSONS): + topwrap specification ips/*.yaml + topwrap dataflow -d design.yaml ips/*.yaml + +clean: + rm -f $(JSONS) diff --git a/examples/ir_examples/interconnect/design.yaml b/examples/ir_examples/interconnect/design.yaml new file mode 100644 index 0000000..8b41b12 --- /dev/null +++ b/examples/ir_examples/interconnect/design.yaml @@ -0,0 +1,63 @@ +external: + ports: + in: + - clk + - rst + interfaces: + in: + - ext_manager + +ips: + cpu: + file: ips/cpu.yaml + wb_pass: + file: ips/wb_passthrough.yaml + mem: + file: ips/mem.yaml + dsp: + file: ips/dsp.yaml + +design: + ports: + cpu: &clkrst + clk: clk + rst: rst + mem: *clkrst + dsp: *clkrst + + parameters: + mem: + WIDTH: 8 + DEPTH: 0xFFFF + wb_pass: + DW: 8 + + interfaces: + wb_pass: + wb_in: ext_manager + + interconnects: + wishbone_bus: + clock: clk + reset: rst + type: wishbone_roundrobin + + params: + addr_width: 32 + data_width: 8 + granularity: 8 + features: [err, stall] + + managers: + cpu: [bus_manager] + wb_pass: [wb_out] + + subordinates: + mem: + bus: + address: 0 + size: 0xFFFF + dsp: + bus: + address: 0x10000 + size: 0xFF diff --git a/examples/ir_examples/interconnect/ips/cpu.yaml b/examples/ir_examples/interconnect/ips/cpu.yaml new file mode 100644 index 0000000..810534e --- /dev/null +++ b/examples/ir_examples/interconnect/ips/cpu.yaml @@ -0,0 +1,23 @@ +name: example_cpu + +signals: + in: + - clk + - rst + +interfaces: + bus_manager: + type: wishbone + mode: manager + signals: + out: + cyc: o_wb_cyc + stb: o_wb_stb + adr: [o_wb_adr, 31, 0] + dat_w: [o_wb_dat, 7, 0] + we: o_wb_we + in: + dat_r: [i_wb_dat, 7, 0] + ack: i_wb_ack + stall: i_wb_stall + err: i_wb_err diff --git a/examples/ir_examples/interconnect/ips/dsp.yaml b/examples/ir_examples/interconnect/ips/dsp.yaml new file mode 100644 index 0000000..e7884bc --- /dev/null +++ b/examples/ir_examples/interconnect/ips/dsp.yaml @@ -0,0 +1,27 @@ +name: dsp_block + +signals: + in: + - clk + - rst + +parameters: + WIDTH: 8 + RESOLUTION: 1024 + +interfaces: + bus: + type: wishbone + mode: subordinate + signals: + in: + cyc: i_cyc + stb: i_stb + adr: [i_adr, 7, 0] + dat_w: [i_dat, WIDTH-1, 0] + we: i_we + out: + dat_r: [o_dat, WIDTH-1, 0] + ack: o_ack + stall: o_stall + err: o_err diff --git a/examples/ir_examples/interconnect/ips/mem.yaml b/examples/ir_examples/interconnect/ips/mem.yaml new file mode 100644 index 0000000..e76ebd6 --- /dev/null +++ b/examples/ir_examples/interconnect/ips/mem.yaml @@ -0,0 +1,27 @@ +name: memory_block + +signals: + in: + - clk + - rst + +parameters: + WIDTH: 32 + DEPTH: 0 + +interfaces: + bus: + type: wishbone + mode: subordinate + signals: + in: + cyc: i_cyc + stb: i_stb + adr: [i_adr, 31, 0] + dat_w: [i_dat, WIDTH-1, 0] + we: i_we + out: + dat_r: [o_dat, WIDTH-1, 0] + ack: o_ack + stall: o_stall + err: o_err diff --git a/examples/ir_examples/interconnect/ips/wb_passthrough.yaml b/examples/ir_examples/interconnect/ips/wb_passthrough.yaml new file mode 100644 index 0000000..6390a9d --- /dev/null +++ b/examples/ir_examples/interconnect/ips/wb_passthrough.yaml @@ -0,0 +1,38 @@ +name: wishbone_passthrough + +parameters: + AW: 32 + DW: 32 + +interfaces: + wb_in: + type: wishbone + mode: subordinate + signals: + in: + cyc: i_cyc + stb: i_stb + adr: [i_adr, AW-1, 0] + dat_w: [i_dat_w, DW-1, 0] + we: i_we + out: + ack: o_ack + dat_r: [o_dat_r, DW-1, 0] + stall: o_stall + err: o_err + + wb_out: + type: wishbone + mode: manager + signals: + out: + cyc: o_cyc + stb: o_stb + adr: [o_adr, AW-1, 0] + dat_w: [o_dat_w, DW-1, 0] + we: o_we + in: + ack: i_ack + dat_r: [i_dat_r, DW-1, 0] + stall: i_stall + err: i_err diff --git a/examples/ir_examples/interface/Makefile b/examples/ir_examples/interface/Makefile new file mode 100644 index 0000000..b3ddc7a --- /dev/null +++ b/examples/ir_examples/interface/Makefile @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +JSONS = kpm_spec.json kpm_dataflow.json + +all: $(JSONS) + +$(JSONS): + topwrap specification ips/*.yaml + topwrap dataflow -d design.yaml ips/*.yaml + +clean: + rm -f $(JSONS) diff --git a/examples/ir_examples/interface/design.yaml b/examples/ir_examples/interface/design.yaml new file mode 100644 index 0000000..be6d6b7 --- /dev/null +++ b/examples/ir_examples/interface/design.yaml @@ -0,0 +1,26 @@ +design: + ports: + streamer: + clk: clk + rst: rst + receiver: + clk: clk + rst: rst + noise: 2888 + interfaces: + streamer: + io: [receiver, io] + +external: + ports: + in: + - clk + - rst + inout: + - [receiver, ext] + +ips: + streamer: + file: ips/streamer.yaml + receiver: + file: ips/receiver.yaml diff --git a/examples/ir_examples/interface/ips/receiver.yaml b/examples/ir_examples/interface/ips/receiver.yaml new file mode 100644 index 0000000..a168d80 --- /dev/null +++ b/examples/ir_examples/interface/ips/receiver.yaml @@ -0,0 +1,17 @@ +name: axis_receiver + +signals: + in: + - clk + - rst + - [noise, 15, 0] + inout: + - [ext, 31, 0] + +interfaces: + io: + type: AXI4Stream + mode: subordinate + signals: + in: + TDATA: [dat_i, 31, 0] diff --git a/examples/ir_examples/interface/ips/streamer.yaml b/examples/ir_examples/interface/ips/streamer.yaml new file mode 100644 index 0000000..a42dab0 --- /dev/null +++ b/examples/ir_examples/interface/ips/streamer.yaml @@ -0,0 +1,20 @@ +name: axis_streamer + +signals: + in: + - clk + - rst + +interfaces: + io: + type: AXI4Stream + mode: manager + signals: + out: + TDATA: [dat_o, 31, 0] + + # PORT SLICING + # Use bit 0 of the 5 bit "ctrl_o" signal for the TVALID signal + TVALID: [ctrl_o, 4, 0, 0, 0] + # Use bits 4..1 for the TKEEP signal + TKEEP: [ctrl_o, 4, 0, 4, 1] diff --git a/examples/ir_examples/simple/Makefile b/examples/ir_examples/simple/Makefile new file mode 100644 index 0000000..b3ddc7a --- /dev/null +++ b/examples/ir_examples/simple/Makefile @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +JSONS = kpm_spec.json kpm_dataflow.json + +all: $(JSONS) + +$(JSONS): + topwrap specification ips/*.yaml + topwrap dataflow -d design.yaml ips/*.yaml + +clean: + rm -f $(JSONS) diff --git a/examples/ir_examples/simple/design.yaml b/examples/ir_examples/simple/design.yaml new file mode 100644 index 0000000..80f7d21 --- /dev/null +++ b/examples/ir_examples/simple/design.yaml @@ -0,0 +1,36 @@ +external: + ports: + in: + - clk + - rst + - sel_gen + out: + - rnd_bit + +ips: + 2mux: + file: ips/2mux.yaml + gen1: + file: ips/lfsr_gen.yaml + gen2: + file: ips/lfsr_gen.yaml + +design: + parameters: + 2mux: + WIDTH: 128 + gen1: + WIDTH: 128 + SEED: 1337 + gen2: + WIDTH: 128 + ports: + 2mux: + gen_sel: sel_gen + gen1: [gen1, gen_out] + gen2: [gen2, gen_out] + out: rnd_bit + gen1: &clkrst + clk: clk + rst: rst + gen2: *clkrst diff --git a/examples/ir_examples/simple/ips/2mux.yaml b/examples/ir_examples/simple/ips/2mux.yaml new file mode 100644 index 0000000..c9e61f8 --- /dev/null +++ b/examples/ir_examples/simple/ips/2mux.yaml @@ -0,0 +1,13 @@ +name: 2mux_compressor + +parameters: + WIDTH: 64 + OUT_WIDTH: 1 + +signals: + in: + - gen_sel + - [gen1, WIDTH-1, 0] + - [gen2, WIDTH-1, 0] + out: + - [out, OUT_WIDTH-1, 0] diff --git a/examples/ir_examples/simple/ips/lfsr_gen.yaml b/examples/ir_examples/simple/ips/lfsr_gen.yaml new file mode 100644 index 0000000..bfb1da6 --- /dev/null +++ b/examples/ir_examples/simple/ips/lfsr_gen.yaml @@ -0,0 +1,12 @@ +name: lfsr_gen + +parameters: + WIDTH: 64 + SEED: 1 + +signals: + in: + - clk + - rst + out: + - [gen_out, WIDTH-1, 0] diff --git a/noxfile.py b/noxfile.py index 84ab346..49a317d 100644 --- a/noxfile.py +++ b/noxfile.py @@ -158,8 +158,8 @@ def doc_gen(session: nox.Session) -> None: session.install(".[parse]") with TemporaryDirectory() as tmpdir, TemporaryFile(mode="w+") as errfile: shutil.copytree(Path("."), tmpdir, dirs_exist_ok=True) - for example in (Path(tmpdir) / "examples").iterdir(): - with session.chdir(example): + for example in (Path(tmpdir) / "examples").glob("**/Makefile"): + with session.chdir(example.parent): try: session.run( "make", @@ -176,11 +176,12 @@ def doc_gen(session: nox.Session) -> None: continue print("\n".join(stderr), file=sys.stderr) raise + name = "_".join(example.parent.parts[len(Path(tmpdir).parts) + 1 :]) shutil.move( - example / "kpm_spec.json", f"docs/build/kpm_jsons/spec_{example.name}.json" + example.parent / "kpm_spec.json", f"docs/build/kpm_jsons/spec_{name}.json" ) shutil.move( - example / "kpm_dataflow.json", f"docs/build/kpm_jsons/data_{example.name}.json" + example.parent / "kpm_dataflow.json", f"docs/build/kpm_jsons/data_{name}.json" ) session.install(".[docs]")