Skip to content

Instantly share code, notes, and snippets.

@josyb
Last active August 24, 2018 12:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josyb/f9d0a79f4a8d8c603cf486de6a5da1d2 to your computer and use it in GitHub Desktop.
Save josyb/f9d0a79f4a8d8c603cf486de6a5da1d2 to your computer and use it in GitHub Desktop.
Conversion of nested top-level interfaces
'''
Created on 23 aug. 2018
@author: josy
'''
from __future__ import print_function
from myhdl import Signal, intbv, block, always_comb, always_seq, ResetSignal
# making up something sensible or even useful
class EncoderUD(object):
def __init__(self):
self.up = Signal(bool(0))
self.down = Signal(bool(0))
self.zero = Signal(bool(0))
class TableXY(object):
def __init__(self):
self.x = EncoderUD()
self.y = EncoderUD()
class Cartesian2D(object):
def __init__(self):
self.x = Signal(intbv(0, -2 ** 15, 2 ** 15))
self.y = Signal(intbv(0, -2 ** 15, 2 ** 15))
@block
def XYTable(Clk, Reset, Table, Position):
'''
Encoding the X,Y position of an XY Table using two Encoders
Clk, Reset: as usual
Table: an TableXY() object giving us the input
Position: an Cartesian2D() object telling us the position
'''
# we need some local counter signals
lposx = Signal(intbv(0, -2 ** 15, 2 ** 15))
lposy = Signal(intbv(0, -2 ** 15, 2 ** 15))
@always_seq(Clk.posedge, reset=Reset)
def synch():
if Table.x.zero:
lposx.next = 0
elif Table.x.up:
if lposx < 2 ** 15:
lposx.next = lposx + 1
elif Table.x.down:
if lposx > -2 ** 15:
lposx.next = lposx - 1
if Table.y.zero:
lposy.next = 0
elif Table.y.up:
if lposy < 2 ** 15:
lposy.next = lposy + 1
elif Table.y.down:
if lposy > -2 ** 15:
lposy.next = lposy - 1
@always_comb
def comb():
Position.x.next = lposx
Position.y.next = lposy
return synch, comb
if __name__ == '__main__':
Clk = Signal(bool(0))
Reset = ResetSignal(0, 1, True)
Table = TableXY()
Position = Cartesian2D()
dfc = XYTable(Clk, Reset, Table, Position)
dfc.name = 'XYTable'
dfc.convert(hdl="VHDL")
-- File: XYTable.vhd
-- Generated by MyHDL 0.10
-- Date: Thu Aug 23 20:26:49 2018
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;
use work.pck_myhdl_010.all;
entity XYTable is
port(
Clk : in std_logic;
Reset : in std_logic;
Table_x_up : in std_logic;
Table_x_down : in std_logic;
Table_x_zero : in std_logic;
Table_y_up : in std_logic;
Table_y_down : in std_logic;
Table_y_zero : in std_logic;
Position_x : out signed(15 downto 0);
Position_y : out signed(15 downto 0)
);
end entity XYTable;
-- Encoding the X,Y position of an XY Table using two Encoders
-- Clk, Reset: as usual
-- Table: an TableXY() object giving us the input
-- Position: an Cartesian2D() object telling us the position
architecture MyHDL of XYTable is
signal lposy : signed(15 downto 0);
signal lposx : signed(15 downto 0);
begin
XYTABLE_SYNCH : process(Clk, Reset) is
begin
if (Reset = '1') then
lposy <= to_signed(0, 16);
lposx <= to_signed(0, 16);
elsif rising_edge(Clk) then
if bool(Table_x_zero) then
lposx <= to_signed(0, 16);
elsif bool(Table_x_up) then
if (lposx < (2 ** 15)) then
lposx <= (lposx + 1);
end if;
elsif bool(Table_x_down) then
if (lposx > (-(2 ** 15))) then
lposx <= (lposx - 1);
end if;
end if;
if bool(Table_y_zero) then
lposy <= to_signed(0, 16);
elsif bool(Table_y_up) then
if (lposy < (2 ** 15)) then
lposy <= (lposy + 1);
end if;
elsif bool(Table_y_down) then
if (lposy > (-(2 ** 15))) then
lposy <= (lposy - 1);
end if;
end if;
end if;
end process XYTABLE_SYNCH;
Position_x <= lposx;
Position_y <= lposy;
end architecture MyHDL;
'''
Created on 23 aug. 2018
@author: josy
'''
from __future__ import print_function
from myhdl import Signal, intbv, block, always_comb, always_seq, ResetSignal, instance, \
delay, StopSimulation
# making up something sensible or even useful
class EncoderUD(object):
def __init__(self):
self.up = Signal(bool(0))
self.down = Signal(bool(0))
self.zero = Signal(bool(0))
class TableXY(object):
def __init__(self):
self.x = EncoderUD()
self.y = EncoderUD()
class Cartesian2D(object):
def __init__(self):
self.x = Signal(intbv(0, -2 ** 15, 2 ** 15))
self.y = Signal(intbv(0, -2 ** 15, 2 ** 15))
class XYTable(object):
def __init__(self, Clk, Reset, Table, Position):
'''
Encoding the X,Y position of an XY Table using two Encoders
Clk, Reset: as usual
Table: an TableXY() object giving us the input
Position: an Cartesian2D() object telling us the position
'''
self.Clk = Clk
self.Reset = Reset
self.Table = Table
self.Position = Position
@block
def rtl(self):
''' the logic '''
# a define/macro
MAX_MAGNITUDE = 2 ** 15 - 1
# we need some local counter signals
lposx = Signal(intbv(0, -2 ** 15, 2 ** 15))
lposy = Signal(intbv(0, -2 ** 15, 2 ** 15))
@always_seq(self.Clk.posedge, reset=self.Reset)
def synch():
if self.Table.x.zero:
lposx.next = 0
elif self.Table.x.up:
if lposx < MAX_MAGNITUDE:
lposx.next = lposx + 1
elif self.Table.x.down:
if lposx > -MAX_MAGNITUDE:
lposx.next = lposx - 1
if self.Table.y.zero:
lposy.next = 0
elif self.Table.y.up:
if lposy < MAX_MAGNITUDE:
lposy.next = lposy + 1
elif self.Table.y.down:
if lposy > -MAX_MAGNITUDE:
lposy.next = lposy - 1
@always_comb
def comb():
self.Position.x.next = lposx
self.Position.y.next = lposy
return synch, comb
@block
def tb_top_level_interfaces():
import random
random.seed = 'We want repeatable randomness :)'
Clk = Signal(bool(0))
Reset = ResetSignal(0, 1, False)
Table = TableXY()
Position = Cartesian2D()
inst = XYTable(Clk, Reset, Table, Position)
inst.name = 'XYTable'
tb_dut = inst.rtl()
T_OPS = 32
xup = [ Signal(bool(random.randint(0, 1))) for _ in range(T_OPS)]
xdown = [ Signal(bool(random.randint(0, 1))) for _ in range(T_OPS)]
yup = [ Signal(bool(random.randint(0, 1))) for _ in range(T_OPS)]
ydown = [ Signal(bool(random.randint(0, 1))) for _ in range(T_OPS)]
tCK = 20
tReset = int(tCK * 3.5)
@instance
def tb_clk():
Clk.next = False
yield delay(int(tCK // 2))
while True:
Clk.next = not Clk
yield delay(int(tCK // 2))
@instance
def tb_stim():
Table.x.up.next = 0
Table.x.down.next = 0
Table.y.up.next = 0
Table.y.down.next = 0
Reset.next = 1
yield delay(tReset)
Reset.next = 0
yield Clk.posedge
for i in range(T_OPS):
Table.x.up.next = xup[i]
Table.x.down.next = xdown[i]
Table.y.up.next = yup[i]
Table.y.down.next = ydown[i]
yield Clk.posedge
print("%d %d" % (Position.x, Position.y))
yield Clk.posedge
Table.x.zero.next = 1
Table.y.zero.next = 1
yield Clk.posedge
Table.x.zero.next = 0
Table.y.zero.next = 0
yield Clk.posedge
assert Position.x == 0
assert Position.y == 0
raise StopSimulation
return tb_dut, tb_clk, tb_stim
@block
def top_xytable(Name, Clk, Reset, Table, Position):
dfc = XYTable(Clk, Reset, Table, Position)
dfcrtl = dfc.rtl()
dfcrtl.name = Name
return dfcrtl
def test_top_level_interfaces_analyze():
Clk = Signal(bool(0))
Reset = ResetSignal(0, 1, True)
Table = TableXY()
Position = Cartesian2D()
dfc = XYTable(Clk, Reset, Table, Position)
assert dfc.analyze_convert() == 0
def test_top_level_interfaces_verify():
inst = tb_top_level_interfaces()
assert inst.verify_convert() == 0
if __name__ == '__main__':
Clk = Signal(bool(0))
Reset = ResetSignal(0, 1, True)
Table = TableXY()
Position = Cartesian2D()
dft = tb_top_level_interfaces()
dft.config_sim(trace=True)
dft.run_sim()
dfc = top_xytable('XYTableC', Clk, Reset, Table, Position)
dfc.name = 'XYTable'
dfc.convert('Verilog')
dfc.convert('VHDL')
-- File: top_xytable.vhd
-- Generated by MyHDL 0.10
-- Date: Fri Aug 24 14:47:58 2018
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;
use work.pck_myhdl_010.all;
entity top_xytable is
port (
Clk: in std_logic;
Reset: in std_logic;
Table_x_up: in std_logic;
Table_x_down: in std_logic;
Table_x_zero: in std_logic;
Table_y_up: in std_logic;
Table_y_down: in std_logic;
Table_y_zero: in std_logic;
Position_x: out signed (15 downto 0);
Position_y: out signed (15 downto 0)
);
end entity top_xytable;
architecture MyHDL of top_xytable is
signal XYTableC_lposy: signed (15 downto 0);
signal XYTableC_lposx: signed (15 downto 0);
begin
TOP_XYTABLE_XYTABLEC_SYNCH: process (Clk, Reset) is
begin
if (Reset = '1') then
XYTableC_lposx <= to_signed(0, 16);
XYTableC_lposy <= to_signed(0, 16);
elsif rising_edge(Clk) then
if bool(Table_x_zero) then
XYTableC_lposx <= to_signed(0, 16);
elsif bool(Table_x_up) then
if (XYTableC_lposx < 32767) then
XYTableC_lposx <= (XYTableC_lposx + 1);
end if;
elsif bool(Table_x_down) then
if (XYTableC_lposx > (-32767)) then
XYTableC_lposx <= (XYTableC_lposx - 1);
end if;
end if;
if bool(Table_y_zero) then
XYTableC_lposy <= to_signed(0, 16);
elsif bool(Table_y_up) then
if (XYTableC_lposy < 32767) then
XYTableC_lposy <= (XYTableC_lposy + 1);
end if;
elsif bool(Table_y_down) then
if (XYTableC_lposy > (-32767)) then
XYTableC_lposy <= (XYTableC_lposy - 1);
end if;
end if;
end if;
end process TOP_XYTABLE_XYTABLEC_SYNCH;
Position_x <= XYTableC_lposx;
Position_y <= XYTableC_lposy;
end architecture MyHDL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment