Obsolete, scheduled for removal
Status notes:
from cyhdl import *
Byte = Signal.Type(intbv, 8)
Bool = Signal.Type(bool)
@block
def lfsr8(clk : ClkSignal, ce : Bool, reset : ResetSignal, dout : Byte.Output,
RVAL : int = 1):
"""LFSR with all states"""
v = Signal(intbv(RVAL)[8:])
fb = Signal(bool())
e = v[7:0] == 0
@always_seq(clk.posedge, reset)
def worker():
if ce == 1:
v.next = concat(v[6], v[5], v[4], v[3] ^ fb, v[2] ^ fb, v[1] ^ fb, v[0], fb)
@always_comb
def assign():
fb.next = v[7] ^ e
dout.next = v
return instances()
# Wrapper hack to use local dictionary for instance naming
def use_local_names(arg):
arg.use_local_names = True
return arg
@use_local_names
@block
def unit_count(clk : ClkSignal, ce: Signal, reset : ResetSignal, q : Signal.Output):
c, d = [ Signal(intbv(0)[8:]) for _ in range(2) ]
inst_lfsr = lfsr8(clk, ce, reset, d, RVAL = 0xfa)
@always_seq(clk.posedge, reset)
def counter():
c.next = c + 1
# q.next = d ^ c
wires = [ q.wireup(d ^ c) ]
return instances()
from myirl.targets import pyosys
def test_expr(tgt):
ce = Signal(bool())
clk = ClkSignal()
reset = ResetSignal(0, 1, isasync = True)
q = Signal(intbv()[8:])
t = unit_count(clk, ce, reset, q)
designs = t.elab(tgt, elab_all = True)
return designs[0]
tgt = pyosys.RTLIL("top")
design = test_expr(tgt)
design.display_rtl(selection = "unit_count", fmt='dot')
# design.display_rtl(selection = "lfsr8", fmt='dot')
Adding module with name `lfsr8` Adding module with name `unit_count` FINALIZE implementation `unit_count` of `unit_count` -- Running command `hierarchy -top \unit_count' -- 1. Executing HIERARCHY pass (managing design hierarchy). 1.1. Analyzing design hierarchy.. Top module: \unit_count Used module: \lfsr8 1.2. Analyzing design hierarchy.. Top module: \unit_count Used module: \lfsr8 Removed 0 unused modules.
The @use_local_names
construct sets the myHDL instance variable names for the identifier.
Note: Pan and zoom may not work on some browsers.
from yosys import display
display.display_dot(design.name)
Note that and
, or
and not
boolean constructs are no longer allowed with signals. Also keep in mind that the test bench below is a co-simulation testbench:
inst
runs as compiled hardware simulation@sim.always
and @sequence
is native Python.from yosys.simulator import CXXRTL as Sim
from cyrite.simulation import sim
@sim.testbench(Sim, time_unit = 'ns')
def testbench():
clk = ClkSignal()
reset = ResetSignal(1, 1, isasync = False)
ce = Signal(bool())
a = Signal(intbv()[8:])
inst = unit_count(clk, ce, reset, a)
@sim.always(delay(2))
def clkgen():
clk.next = ~ clk
@sim.sequence
def reset_seq():
yield delay(21)
reset.next = False
yield delay(1)
ce.next = True
yield delay(20)
return instances()
The simulation is executed using the .run
method below. Note that the simulation may not be fully 'delta' accurate and will only serve for synchronous designs.
Note: It is mandatory to yield an initial delay in the sequential code to properly arm the concurrent process scheduling.
def test_simulation(n):
t = testbench()
assert t._uut.obj.ctx == unit_count.ctx
t.run(n)
return t
t = test_simulation(2000)
Module unit_count: Existing instance unit_count, rename to unit_count_1 Module unit_count: Existing instance lfsr8, rename to lfsr8_1 Adding module with name `lfsr8_1` Adding module with name `unit_count_1` FINALIZE implementation `unit_count_1` of `unit_count` -- Running command `tee -q show -format dot -prefix top unit_count' -- -- Running command `hierarchy -top \unit_count_1' -- 3. Executing HIERARCHY pass (managing design hierarchy). 3.1. Analyzing design hierarchy.. Top module: \unit_count_1 Used module: \lfsr8_1 3.2. Analyzing design hierarchy.. Top module: \unit_count_1 Used module: \lfsr8_1 Removed 0 unused modules. -- Running command `write_cxxrtl -namespace unit_count -header /tmp/myirl_unit_count_i66h_n71/unit_count_rtl.cpp' -- 4. Executing CXXRTL backend. 4.1. Executing HIERARCHY pass (managing design hierarchy). 4.1.1. Analyzing design hierarchy.. Top module: \unit_count_1 Used module: \lfsr8_1 4.1.2. Analyzing design hierarchy.. Top module: \unit_count_1 Used module: \lfsr8_1 Removed 0 unused modules. 4.2. Executing FLATTEN pass (flatten design). Deleting now unused module lfsr8_1. <suppressed ~1 debug messages> 4.3. Executing PROC pass (convert processes to netlists). 4.3.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. 4.3.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). Removed a total of 0 dead cases. 4.3.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). Removed 0 redundant assignments. Promoted 0 assignments to connections. 4.3.4. Executing PROC_INIT pass (extract init attributes). 4.3.5. Executing PROC_ARST pass (detect async resets in processes). 4.3.6. Executing PROC_ROM pass (convert switches to ROMs). Converted 0 switches. 4.3.7. Executing PROC_MUX pass (convert decision trees to multiplexers). 4.3.8. Executing PROC_DLATCH pass (convert process syncs to latches). 4.3.9. Executing PROC_DFF pass (convert process syncs to FFs). 4.3.10. Executing PROC_MEMWR pass (convert process memory writes to cells). 4.3.11. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. 4.3.12. Executing OPT_EXPR pass (perform const folding). Optimizing module unit_count_1. <suppressed ~2 debug messages>
Using '/tmp/myirl_unit_count_i66h_n71/' for output
Compiling /tmp/myirl_unit_count_i66h_n71/unit_count.pyx because it changed. [1/1] Cythonizing /tmp/myirl_unit_count_i66h_n71/unit_count.pyx running build_ext building 'runtime.unit_count' extension creating build/temp.linux-x86_64-3.10/tmp/myirl_unit_count_i66h_n71 gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -DCOSIM_NAMESPACE=unit_count -Iruntime -I/tmp/myirl_unit_count_i66h_n71/ -I/usr/share/yosys/include/backends/cxxrtl/runtime -I/usr/local/include/python3.10 -c /tmp/myirl_unit_count_i66h_n71/unit_count.cpp -o build/temp.linux-x86_64-3.10/tmp/myirl_unit_count_i66h_n71/unit_count.o gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -DCOSIM_NAMESPACE=unit_count -Iruntime -I/tmp/myirl_unit_count_i66h_n71/ -I/usr/share/yosys/include/backends/cxxrtl/runtime -I/usr/local/include/python3.10 -c /tmp/myirl_unit_count_i66h_n71/unit_count_rtl.cpp -o build/temp.linux-x86_64-3.10/tmp/myirl_unit_count_i66h_n71/unit_count_rtl.o g++ -pthread -shared -Wl,--strip-all build/temp.linux-x86_64-3.10/tmp/myirl_unit_count_i66h_n71/unit_count.o build/temp.linux-x86_64-3.10/tmp/myirl_unit_count_i66h_n71/unit_count_rtl.o -L/usr/local/lib -o build/lib.linux-x86_64-3.10/runtime/unit_count.cpython-310-x86_64-linux-gnu.so copying build/lib.linux-x86_64-3.10/runtime/unit_count.cpython-310-x86_64-linux-gnu.so -> runtime Open for writing: testbench.vcd
DEBUG STOP PROCESS reset_seq
The resulting test bench file: testbench.vcd
When the .elab()
method is called, the design is elaborated as RTLIL and a list of design elements is returned, the first being a RTLIL Design handle.
The .finalize()
method is called last inside elaboration, which can perform some optimizations or emissions to specific targets.
class MyRTL(pyosys.RTLIL):
def finalize(self, top, objs = None):
tname = top.name
design = self._design
design.run("hierarchy -top %s" % tname)
print(80 * '=')
design.write_verilog(name = top.obj.name)
design.run("flatten; ls; select %s; stat" % tname)
return [design]
The .finalize()
function must return the created elements in a list, which is in turn returned from the .elab()
call.
tgt = MyRTL("top2")
design = test_expr(tgt)
Module unit_count: Existing instance unit_count, rename to unit_count_2 Module unit_count: Existing instance lfsr8, rename to lfsr8_2 Adding module with name `lfsr8_2` Adding module with name `unit_count_2` ================================================================================ <suppressed ~12 debug messages> -- Running command `tee -q hierarchy -top unit_count_2' -- -- Running command `ls; check' -- 6. Executing CHECK pass (checking for obvious problems). Found and reported 0 problems. -- Running command `hierarchy -check' -- 7. Executing HIERARCHY pass (managing design hierarchy). -- Running command `write_verilog unit_count.v' -- 8. Executing Verilog backend. 8.1. Executing BMUXMAP pass. 8.2. Executing DEMUXMAP pass. Dumping module `\lfsr8_2'. Dumping module `\unit_count_2'. -- Running command `tee -q flatten; ls; select unit_count_2; stat' -- 1 modules: unit_count_2 10. Printing statistics.
!cat unit_count_mapped.v
/* Generated by Yosys 0.13+3 (git sha1 4656b0171, gcc 10.2.1-6 -Og -fPIC) */ module lfsr8_2(clk, ce, reset, dout); wire [7:0] _00_; wire [-1:0] _01_; wire _02_; wire _03_; wire _04_; wire _05_; wire [7:0] _06_; wire _07_; wire _08_; wire _09_; wire [7:0] _10_; reg [7:0] _11_; wire [7:0] _12_; wire [7:0] _13_; input ce; input clk; output [7:0] dout; wire fb; input reset; wire [7:0] v; assign _08_ = v[6:0] == 7'h00; assign _09_ = v[7] ^ _08_; assign _05_ = ce == 1'h1; assign _03_ = v[2] ^ fb; assign _04_ = v[3] ^ fb; assign _06_ = _05_ ? _00_ : _13_; assign _02_ = v[1] ^ fb; always @(posedge clk, posedge reset) if (reset) _11_ <= 8'hfa; else _11_ <= _06_; assign _00_ = { v[6:4], _04_, _03_, _02_, v[0], fb }; assign v = _11_; assign _13_ = _11_; assign _07_ = _09_; assign _10_ = v; assign fb = _07_; assign dout = _10_; endmodule (* top = 1 *) module unit_count_2(clk, ce, reset, q); wire [7:0] _0_; wire [8:0] _1_; wire [7:0] _2_; reg [7:0] _3_; wire [7:0] _4_; wire [7:0] c; input ce; input clk; wire [7:0] d; output [7:0] q; input reset; assign _2_ = d ^ c; assign _1_ = c + 8'h01; always @(posedge clk, posedge reset) if (reset) _3_ <= 8'h00; else _3_ <= _0_; lfsr8_2 inst_lfsr ( .ce(ce), .clk(clk), .dout(d), .reset(reset) ); assign _0_ = _1_[7:0]; assign c = _3_; assign q = _2_; endmodule
Some constructs that work for the VHDL target may not yet be supported: