add write/readback tests, seems to pass
This commit is contained in:
parent
0bbdf4faa6
commit
b4fb79bc8e
|
|
@ -5,23 +5,12 @@ module top_level (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
|
|
||||||
input wire uart_txd_in,
|
input wire uart_txd_in,
|
||||||
output logic uart_rxd_out,
|
output logic uart_rxd_out);
|
||||||
|
|
||||||
input wire btnu,
|
logic probe0;
|
||||||
input wire btnd,
|
logic [1:0] probe1;
|
||||||
input wire btnl,
|
logic [7:0] probe2;
|
||||||
input wire btnr,
|
logic [19:0] probe3;
|
||||||
input wire btnc,
|
|
||||||
|
|
||||||
input wire [15:0] sw,
|
|
||||||
|
|
||||||
output logic [15:0] led,
|
|
||||||
output logic led16_b,
|
|
||||||
output logic led16_g,
|
|
||||||
output logic led16_r,
|
|
||||||
output logic led17_b,
|
|
||||||
output logic led17_g,
|
|
||||||
output logic led17_r);
|
|
||||||
|
|
||||||
manta manta_inst (
|
manta manta_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
|
|
@ -29,19 +18,14 @@ module top_level (
|
||||||
.rx(uart_txd_in),
|
.rx(uart_txd_in),
|
||||||
.tx(uart_rxd_out),
|
.tx(uart_rxd_out),
|
||||||
|
|
||||||
.btnu(btnu),
|
.probe0(probe0),
|
||||||
.btnd(btnd),
|
.probe1(probe1),
|
||||||
.btnl(btnl),
|
.probe2(probe2),
|
||||||
.btnr(btnr),
|
.probe3(probe3),
|
||||||
.btnc(btnc),
|
.probe4(probe0),
|
||||||
.sw(sw),
|
.probe5(probe1),
|
||||||
.led(led),
|
.probe6(probe2),
|
||||||
.led16_b(led16_b),
|
.probe7(probe3));
|
||||||
.led16_g(led16_g),
|
|
||||||
.led16_r(led16_r),
|
|
||||||
.led17_b(led17_b),
|
|
||||||
.led17_g(led17_g),
|
|
||||||
.led17_r(led17_r));
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
from manta import Manta
|
||||||
|
from random import randint
|
||||||
|
m = Manta('manta.yaml')
|
||||||
|
|
||||||
|
n_tests = 100
|
||||||
|
for i in range(n_tests):
|
||||||
|
print(f"-> Beginning test {i} of {n_tests}")
|
||||||
|
probe4 = randint(0, 1)
|
||||||
|
m.io_core.probe4.set(probe4)
|
||||||
|
assert m.io_core.probe0.get() == probe4
|
||||||
|
|
||||||
|
probe5 = randint(0, 3)
|
||||||
|
m.io_core.probe5.set(probe5)
|
||||||
|
assert m.io_core.probe1.get() == probe5
|
||||||
|
|
||||||
|
probe6 = randint(0, 255)
|
||||||
|
m.io_core.probe6.set(probe6)
|
||||||
|
assert m.io_core.probe2.get() == probe6
|
||||||
|
|
||||||
|
probe7 = randint(0, (2**20)-1)
|
||||||
|
m.io_core.probe7.set(probe7)
|
||||||
|
assert m.io_core.probe3.get() == probe7
|
||||||
|
|
@ -11,49 +11,49 @@ create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {cl
|
||||||
|
|
||||||
##Switches
|
##Switches
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
|
#set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
|
||||||
set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
|
#set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
|
||||||
set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
|
#set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
|
||||||
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
|
#set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
|
||||||
set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
|
#set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
|
||||||
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
|
#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
|
||||||
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
|
#set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
|
||||||
set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
|
#set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
|
||||||
set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
|
#set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
|
||||||
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
|
#set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
|
||||||
set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
|
#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
|
||||||
set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
|
#set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
|
||||||
set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
|
#set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
|
||||||
set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
|
#set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
|
||||||
set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
|
#set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
|
||||||
set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
|
#set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
|
||||||
|
|
||||||
|
|
||||||
## LEDs
|
## LEDs
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
|
#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
|
||||||
set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
|
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
|
||||||
set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
|
#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
|
||||||
set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
|
#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
|
||||||
set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
|
#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
|
||||||
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
|
#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
|
||||||
set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
|
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
|
||||||
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
|
#set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
|
||||||
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
|
#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
|
||||||
set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
|
#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
|
||||||
set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { led[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
|
#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { led[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
|
||||||
set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { led[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
|
#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { led[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
|
||||||
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { led[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
|
#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { led[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
|
||||||
set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { led[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
|
#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { led[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
|
||||||
set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { led[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
|
#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { led[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
|
||||||
set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
|
#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
|
||||||
|
#
|
||||||
set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { led16_b }]; #IO_L5P_T0_D06_14 Sch=led16_b
|
#set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { led16_b }]; #IO_L5P_T0_D06_14 Sch=led16_b
|
||||||
set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { led16_g }]; #IO_L10P_T1_D14_14 Sch=led16_g
|
#set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { led16_g }]; #IO_L10P_T1_D14_14 Sch=led16_g
|
||||||
set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { led16_r }]; #IO_L11P_T1_SRCC_14 Sch=led16_r
|
#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { led16_r }]; #IO_L11P_T1_SRCC_14 Sch=led16_r
|
||||||
set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { led17_b }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b
|
#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { led17_b }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b
|
||||||
set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { led17_g }]; #IO_0_14 Sch=led17_g
|
#set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { led17_g }]; #IO_0_14 Sch=led17_g
|
||||||
set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { led17_r }]; #IO_L11N_T1_SRCC_14 Sch=led17_r
|
#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { led17_r }]; #IO_L11N_T1_SRCC_14 Sch=led17_r
|
||||||
|
|
||||||
|
|
||||||
##7 segment display
|
##7 segment display
|
||||||
|
|
@ -82,11 +82,11 @@ set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { led17_
|
||||||
|
|
||||||
#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
|
#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { btnc }]; #IO_L9P_T1_DQS_14 Sch=btnc
|
#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { btnc }]; #IO_L9P_T1_DQS_14 Sch=btnc
|
||||||
set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu
|
#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu
|
||||||
set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btnl }]; #IO_L12P_T1_MRCC_14 Sch=btnl
|
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btnl }]; #IO_L12P_T1_MRCC_14 Sch=btnl
|
||||||
set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btnr }]; #IO_L10N_T1_D15_14 Sch=btnr
|
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btnr }]; #IO_L10N_T1_D15_14 Sch=btnr
|
||||||
set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
|
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
|
||||||
|
|
||||||
|
|
||||||
##Pmod Headers
|
##Pmod Headers
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,56 @@
|
||||||
from ..utils import *
|
from ..utils import *
|
||||||
from math import ceil
|
from math import ceil
|
||||||
|
|
||||||
class IOCoreProbe:
|
class InputProbe:
|
||||||
def __init__(self, name, width, base_addr, initial_value = None):
|
def __init__(self, name, width, base_addr, strobe_addr, interface):
|
||||||
assert isinstance(width, int), f"Probe {name} must have integer width."
|
assert isinstance(width, int), f"Probe {name} must have integer width."
|
||||||
assert width > 0, f"Probe {name} must have positive width."
|
assert width > 0, f"Probe {name} must have positive width."
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.width = width
|
self.width = width
|
||||||
self.initial_value = initial_value
|
self.strobe_addr = strobe_addr
|
||||||
|
self.interface = interface
|
||||||
|
|
||||||
n_addrs = ceil(self.width / 16)
|
n_addrs = ceil(self.width / 16)
|
||||||
self.addrs = list(range(base_addr, base_addr + n_addrs))
|
self.addrs = list(range(base_addr, base_addr + n_addrs))
|
||||||
self.brackets = "" if self.width == 1 else f"[{self.width-1}:0] "
|
self.brackets = "" if self.width == 1 else f"[{self.width-1}:0] "
|
||||||
|
|
||||||
|
def pulse_strobe_register(self):
|
||||||
|
# pulse the strobe register
|
||||||
|
self.interface.write(self.strobe_addr, 1)
|
||||||
|
self.interface.write(self.strobe_addr, 0)
|
||||||
|
strobe = self.interface.read(self.strobe_addr)
|
||||||
|
if strobe != 0:
|
||||||
|
raise ValueError("Unable to set strobe register to zero!")
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
self.pulse_strobe_register()
|
||||||
|
return pack_16bit_words(self.interface.read(self.addrs))
|
||||||
|
|
||||||
|
class OutputProbe(InputProbe):
|
||||||
|
def __init__(self, name, width, base_addr, strobe_addr, interface, initial_value):
|
||||||
|
super().__init__(name, width, base_addr, strobe_addr, interface)
|
||||||
|
self.initial_value = initial_value
|
||||||
|
|
||||||
|
def set(self, value):
|
||||||
|
# check that value is an integer
|
||||||
|
assert isinstance(value, int), "Value must be an integer."
|
||||||
|
|
||||||
|
# check that value is within range for the width of the probe
|
||||||
|
if value > 0:
|
||||||
|
assert value <= (2**self.width) - 1, f"Unsigned value too large for probe of width {self.width}"
|
||||||
|
|
||||||
|
elif value < 0:
|
||||||
|
assert abs(value) <= (2**(self.width-1))-1, f"Signed value too large for probe of width {self.width}"
|
||||||
|
|
||||||
|
self.interface.write(self.addrs, unpack_16bit_words(value, len(self.addrs)))
|
||||||
|
self.pulse_strobe_register()
|
||||||
|
|
||||||
class IOCore:
|
class IOCore:
|
||||||
def __init__(self, config, name, base_addr, interface):
|
def __init__(self, config, name, base_addr, interface):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.base_addr = base_addr
|
self.base_addr = base_addr
|
||||||
|
self.interface = interface
|
||||||
|
|
||||||
# make sure we have ports defined
|
# make sure we have ports defined
|
||||||
assert ('inputs' in config) or ('outputs' in config), "No input or output ports specified."
|
assert ('inputs' in config) or ('outputs' in config), "No input or output ports specified."
|
||||||
|
|
@ -38,7 +71,7 @@ class IOCore:
|
||||||
last_used_addr = self.base_addr # start at one since strobe register is at BASE_ADDR
|
last_used_addr = self.base_addr # start at one since strobe register is at BASE_ADDR
|
||||||
if 'inputs' in config:
|
if 'inputs' in config:
|
||||||
for name, width in config["inputs"].items():
|
for name, width in config["inputs"].items():
|
||||||
probe = IOCoreProbe(name, width, last_used_addr + 1)
|
probe = InputProbe(name, width, last_used_addr + 1, self.base_addr, interface)
|
||||||
last_used_addr = probe.addrs[-1]
|
last_used_addr = probe.addrs[-1]
|
||||||
self.input_probes.append(probe)
|
self.input_probes.append(probe)
|
||||||
|
|
||||||
|
|
@ -59,7 +92,7 @@ class IOCore:
|
||||||
raise ValueError(f"Unable to determine probe width and initial value for {name}")
|
raise ValueError(f"Unable to determine probe width and initial value for {name}")
|
||||||
|
|
||||||
# add probe to core
|
# add probe to core
|
||||||
probe = IOCoreProbe(name, width, last_used_addr + 1, initial_value)
|
probe = OutputProbe(name, width, last_used_addr + 1, self.base_addr, interface, initial_value)
|
||||||
last_used_addr = probe.addrs[-1]
|
last_used_addr = probe.addrs[-1]
|
||||||
self.output_probes.append(probe)
|
self.output_probes.append(probe)
|
||||||
|
|
||||||
|
|
@ -67,43 +100,9 @@ class IOCore:
|
||||||
|
|
||||||
# add friendly names to each probe
|
# add friendly names to each probe
|
||||||
# (so users can do io_core.probe.set() and get() for instance)
|
# (so users can do io_core.probe.set() and get() for instance)
|
||||||
for probe in self.input_probes:
|
for probe in self.input_probes + self.output_probes:
|
||||||
setattr(probe, "set", lambda value: self.set(probe, value) )
|
|
||||||
setattr(self, probe.name, probe)
|
setattr(self, probe.name, probe)
|
||||||
|
|
||||||
for probe in self.input_probes:
|
|
||||||
setattr(probe, "set", lambda value: self.set(probe, value) )
|
|
||||||
setattr(probe, "get", self.get(probe) )
|
|
||||||
setattr(self, probe.name, probe)
|
|
||||||
|
|
||||||
|
|
||||||
def get(self, probe):
|
|
||||||
self.pulse_strobe_register()
|
|
||||||
return pack_16bit_words(self.interface.read(probe.addrs))
|
|
||||||
|
|
||||||
def set(self, probe, value):
|
|
||||||
# check that value is an integer
|
|
||||||
assert isinstance(value, int), "Value must be an integer."
|
|
||||||
|
|
||||||
# check that value is within range for the width of the probe
|
|
||||||
if value > 0:
|
|
||||||
assert data <= (2**self.width) - 1, f"Unsigned value too large for probe of width {self.width}"
|
|
||||||
|
|
||||||
elif value < 0:
|
|
||||||
assert abs(data) <= (2**(self.width-1))-1, f"Signed value too large for probe of width {self.width}"
|
|
||||||
|
|
||||||
self.pulse_strobe_register()
|
|
||||||
data = unpack_16_bit_words(value)
|
|
||||||
self.interface.write(probe.addrs, data)
|
|
||||||
|
|
||||||
def pulse_strobe_register(self):
|
|
||||||
# pulse the strobe register
|
|
||||||
self.interface.write(self.base_addr, 1)
|
|
||||||
self.interface.write(self.base_addr, 0)
|
|
||||||
strobe = self.interface.read(self.base_addr)
|
|
||||||
if strobe != 0:
|
|
||||||
raise ValueError("Unable to set strobe register to zero!")
|
|
||||||
|
|
||||||
def hdl_top_level_ports(self):
|
def hdl_top_level_ports(self):
|
||||||
ports = []
|
ports = []
|
||||||
|
|
||||||
|
|
@ -113,7 +112,7 @@ class IOCore:
|
||||||
for probe in self.input_probes:
|
for probe in self.input_probes:
|
||||||
ports.append(f"input wire {probe.brackets}{probe.name}")
|
ports.append(f"input wire {probe.brackets}{probe.name}")
|
||||||
|
|
||||||
for probe in self.input_probes:
|
for probe in self.output_probes:
|
||||||
ports.append(f"output reg {probe.brackets}{probe.name}")
|
ports.append(f"output reg {probe.brackets}{probe.name}")
|
||||||
|
|
||||||
return ports
|
return ports
|
||||||
|
|
@ -202,7 +201,7 @@ class IOCore:
|
||||||
return '\n'.join(lines)
|
return '\n'.join(lines)
|
||||||
|
|
||||||
def gen_output_probe_initial_values(self):
|
def gen_output_probe_initial_values(self):
|
||||||
lines = [f"{p.name} = {p.initial_value}" for p in self.output_probes]
|
lines = [f"{p.name} = {p.initial_value};" for p in self.output_probes]
|
||||||
return '\n'.join(lines)
|
return '\n'.join(lines)
|
||||||
|
|
||||||
def gen_update_input_buffers(self):
|
def gen_update_input_buffers(self):
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ class UARTInterface:
|
||||||
response = inbound_bytes[i:i+7]
|
response = inbound_bytes[i:i+7]
|
||||||
data.append(self.decode_response(response))
|
data.append(self.decode_response(response))
|
||||||
|
|
||||||
if len(data) == 1:
|
if isinstance(addr, int):
|
||||||
return data[0]
|
return data[0]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,26 @@
|
||||||
import pkgutil
|
import pkgutil
|
||||||
|
from math import ceil
|
||||||
|
|
||||||
def pack_16bit_words(data):
|
def pack_16bit_words(data):
|
||||||
"""Takes a list of integers, interprets them as 16-bit integers, and
|
"""Takes a list of integers, interprets them as 16-bit integers, and
|
||||||
concatenates them together in little-endian order."""
|
concatenates them together in little-endian order."""
|
||||||
for d in data:
|
|
||||||
if d > 0:
|
|
||||||
assert d < 2**16-1, "Unsigned integer too large."
|
|
||||||
|
|
||||||
if d < 0:
|
for d in data:
|
||||||
assert d < 2**15-1, "Signed integer too large."
|
if d > 0: assert d < 2**16-1, "Unsigned integer too large."
|
||||||
|
if d < 0: assert d < 2**15-1, "Signed integer too large."
|
||||||
|
|
||||||
return int(''.join([f'{i:016b}' for i in data[::-1]]), 2)
|
return int(''.join([f'{i:016b}' for i in data[::-1]]), 2)
|
||||||
|
|
||||||
def unpack_16bit_words(data):
|
def unpack_16bit_words(data, n_words):
|
||||||
pass
|
"""Takes a integer, interprets it as a set of 16-bit integers
|
||||||
|
concatenated together, and splits it into a list of 16-bit numbers"""
|
||||||
|
|
||||||
|
assert isinstance(data, int), "Behavior is only defined for nonnegative integers."
|
||||||
|
assert data >= 0, "Behavior is only defined for nonnegative integers."
|
||||||
|
|
||||||
|
# convert to binary, split into 16-bit chunks, and then convert back to list of int
|
||||||
|
binary = f'{data:0b}'.zfill(n_words * 16)
|
||||||
|
return [int(binary[i:i+16], 2) for i in range(0, 16 * n_words, 16)][::-1]
|
||||||
|
|
||||||
class VerilogManipulator:
|
class VerilogManipulator:
|
||||||
def __init__(self, filepath=None):
|
def __init__(self, filepath=None):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue