A different, more compact variant, avoiding recursive fun. This one does not confuse CXXRTL with too much combinatorial logic.
import sys
sys.path.insert(0, '../../')
from myirl.emulation.myhdl import *
Bool = Signal.Type(bool)
@block
def bs_stage(wout : Signal.Output,
win : Signal, sh_bit : Signal, stage : int,
ROTATE : (Bool, bool),
LEFT : (Bool, bool),
ASR : (Bool, bool), BITS : int):
j = 2 ** stage
# When ASR is a constant, we optimize to constants as well:
if isinstance(ASR, bool):
if ASR:
pad_msb = j * [ win[BITS-1] ]
else:
pad_msb = [ intbv(0)[j:] ]
else:
pad_msb = j * [ win[BITS-1] & ASR ]
@always_comb
def worker():
if sh_bit == False:
wout.next = win
else:
if ROTATE:
if LEFT:
wout.next = concat(win[BITS-j:0], win[BITS:BITS-j])
else:
wout.next = concat(win[j:0], win[BITS:j])
else:
if LEFT:
wout.next = concat(win[BITS-j:0], *pad_msb)
else:
wout.next = concat(*pad_msb, win[BITS:j])
return instances()
BOOL = (bool, Signal.Type(bool))
@block
def barrel_shifter(clk : ClkSignal,
ce : Signal,
val : Signal,
s : Signal,
result : Signal.Output,
left : BOOL = True,
asr : BOOL = False,
rotate : BOOL = False, W_POWER = 5):
BITS = 2 ** W_POWER
worker = [ Signal(intbv()[BITS:]) for _ in range(W_POWER + 1) ]
inst = [
worker[0].wireup(val),
]
for i in range(W_POWER):
inst += [
bs_stage(worker[i+1], worker[i], s[i], i, rotate, left, asr, BITS)
]
@always(clk.posedge)
def ff():
if ce:
result.next = worker[W_POWER]
return instances()
from simulation import *
from myirl.simulation import print_
from myirl.emulation.factory_class import factory
from myirl.targets import pyosys
class example_design(factory.Module):
def __init__(self, name, simclass, *args, **kwargs):
super().__init__(name, simclass, *args, **kwargs)
self.W_POWER = 4
self.debug = False
# Top level signal set
self.clk = self.ClkSignal(name="clk")
self.ce = self.Signal(bool())
self.val, self.result = [ self.Signal(intbv(0xaa00)[2 ** self.W_POWER:]) for i in range(2) ]
self.result.rename("res")
self.s = self.Signal(intbv()[self.W_POWER:])
self.left = self.Signal(bool())
self.asr = self.Signal(bool())
self.rotate = self.Signal(bool())
def build(self):
return barrel_shifter(
clk = self.clk,
ce = self.ce,
val = self.val,
s = self.s,
result = self.result,
rotate = self.rotate,
left = self.left,
asr = self.asr,
W_POWER = self.W_POWER
)
def emit_rtlil(self, fileprefix):
tgt = pyosys.RTLIL("barrel_shifter")
inst = self.build()
d = inst.elab(tgt)
d[0].write_rtlil(fileprefix)
@factory.testbench('ns')
def tb_rtl(self):
inst = self.build()
clk = self.clk
ce = self.ce
val = self.val
result = self.result
s = self.s
rot, asr, left = self.rotate, self.asr, self.left
@self.always(delay(2))
def clkgen():
clk.next = ~clk
TEST_VALUES = [
(0xdead, True, False, False, 8, 0xad00),
(0x8f01, True, False, False, 15, 0x8000),
(0xdead, False, False, False, 8, 0x00de),
(0xdead, False, True, False, 12, 0xeadd),
# With ASR bit set (only effective with right shift)
(0x8f01, False, False, True, 14, 0xfffe),
]
@self.sequence
def stim():
for item in TEST_VALUES:
ce.next = False
s.next = item[4]
left.next = item[1]
rot.next = item[2]
asr.next = item[3]
val.next = item[0]
yield(clk.posedge)
ce.next = True
yield(clk.posedge)
yield(clk.posedge)
print(result)
assert result == item[5]
raise StopSimulation
return instances()
from myirl.test.ghdl import GHDL
from yosys.simulator import CXXRTL
d = example_design("testbench", CXXRTL)
d.emit_rtlil("barrelshifter")
tb = d.tb_rtl()
print(76 * '=')
tb.run(60)
Module testbench: Existing instance bs_stage, rename to bs_stage_1 Module testbench: Existing instance bs_stage, rename to bs_stage_2 Module testbench: Existing instance bs_stage, rename to bs_stage_3 Elaborating component bs_stage_s16_s16_s1_3_s1_s1_s1_16 Adding module with name `bs_stage_3` Elaborating component bs_stage_s16_s16_s1_2_s1_s1_s1_16 Adding module with name `bs_stage_2` Elaborating component bs_stage_s16_s16_s1_1_s1_s1_s1_16 Adding module with name `bs_stage_1` Elaborating component bs_stage_s16_s16_s1_0_s1_s1_s1_16 Adding module with name `bs_stage` Adding module with name `barrel_shifter` FINALIZE implementation `barrel_shifter` of `barrel_shifter` -- Running command `tee -q hierarchy -top \barrel_shifter' -- -- Running command `write_rtlil barrelshifter.il' -- 2. Executing RTLIL backend. DEBUG: Skip non-simulation type <class '__main__.example_design'> DEBUG: Skip non-simulation type <class 'list'> ============================================================================ Elaborating component bs_stage_s16_s16_s1_3_s1_s1_s1_16 Adding module with name `bs_stage_3` Elaborating component bs_stage_s16_s16_s1_2_s1_s1_s1_16 Adding module with name `bs_stage_2` Elaborating component bs_stage_s16_s16_s1_1_s1_s1_s1_16 Adding module with name `bs_stage_1` Elaborating component bs_stage_s16_s16_s1_0_s1_s1_s1_16 Adding module with name `bs_stage` Adding module with name `barrel_shifter` FINALIZE implementation `barrel_shifter` of `barrel_shifter` Compiling /tmp/barrel_shifter_14d3.pyx because it changed. [1/1] Cythonizing /tmp/barrel_shifter_14d3.pyx running build_ext building 'barrel_shifter_14d3' extension x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -ffile-prefix-map=/build/python3.9-RNBry6/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -ffile-prefix-map=/build/python3.9-RNBry6/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DCOSIM_NAMESPACE=barrel_shifter_14d3 -I../../myirl/../ -I/tmp/ -I/usr/share/yosys/include -I/usr/include/python3.9 -c /tmp/barrel_shifter_14d3.cpp -o build/temp.linux-x86_64-3.9/tmp/barrel_shifter_14d3.o x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -ffile-prefix-map=/build/python3.9-RNBry6/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -ffile-prefix-map=/build/python3.9-RNBry6/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DCOSIM_NAMESPACE=barrel_shifter_14d3 -I../../myirl/../ -I/tmp/ -I/usr/share/yosys/include -I/usr/include/python3.9 -c /tmp/barrel_shifter_14d3_rtl.cpp -o build/temp.linux-x86_64-3.9/tmp/barrel_shifter_14d3_rtl.o x86_64-linux-gnu-g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 -Wl,-z,relro -g -fwrapv -O2 -g -ffile-prefix-map=/build/python3.9-RNBry6/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.9/tmp/barrel_shifter_14d3.o build/temp.linux-x86_64-3.9/tmp/barrel_shifter_14d3_rtl.o -o build/lib.linux-x86_64-3.9/barrel_shifter_14d3.cpython-39-x86_64-linux-gnu.so copying build/lib.linux-x86_64-3.9/barrel_shifter_14d3.cpython-39-x86_64-linux-gnu.so -> Open for writing: tb_rtl.vcd CXXRTL context: SKIP INTERFACE ITEM `W_POWER` <res> : 0xad00 <res> : 0x8000 <res> : 0x00de <res> : 0xeadd <res> : 0xfffe STOP SIMULATION @58