Last active
August 24, 2018 12:50
-
-
Save josyb/f9d0a79f4a8d8c603cf486de6a5da1d2 to your computer and use it in GitHub Desktop.
Conversion of nested top-level interfaces
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
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") | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
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') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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