From db1ceccca1febfdbb147af9aec108d5896f4b627 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 18 Mar 2013 23:57:51 +0100 Subject: [PATCH] fix uart2Csr and update miio example --- examples/de0_nano/build.py | 4 + examples/de0_nano/client/test_MiLa_0.py | 79 ------------- examples/de0_nano/client/test_MiLa_1.py | 62 ---------- .../client/{test_MiIo.py => test_miio.py} | 29 ++--- examples/de0_nano/misc.py | 111 ++++++++++++++++++ examples/de0_nano/top.py | 28 +++-- miscope/bridges/uart2csr/__init__.py | 74 ++++++------ miscope/bridges/uart2csr/tools/__init__.py | 0 miscope/bridges/uart2csr/tools/uart2Csr.py | 59 ++++++++++ miscope/bridges/uart2csr/uart.py | 8 +- miscope/miio.py | 5 +- 11 files changed, 246 insertions(+), 213 deletions(-) delete mode 100644 examples/de0_nano/client/test_MiLa_0.py delete mode 100644 examples/de0_nano/client/test_MiLa_1.py rename examples/de0_nano/client/{test_MiIo.py => test_miio.py} (70%) create mode 100644 examples/de0_nano/misc.py create mode 100644 miscope/bridges/uart2csr/tools/__init__.py create mode 100644 miscope/bridges/uart2csr/tools/uart2Csr.py diff --git a/examples/de0_nano/build.py b/examples/de0_nano/build.py index 43c37fbe..764fe0b2 100644 --- a/examples/de0_nano/build.py +++ b/examples/de0_nano/build.py @@ -10,6 +10,10 @@ def main(): # set pin constraints plat.request("led", 0, obj=soc.led) + + #plat.request("led", 4, obj=soc.uart_rx_event.o) + #plat.request("led", 5, obj=soc.uart_tx_event.o) + #plat.request("led", 7, obj=soc.debug_event.o) plat.request("serial", 0, obj=soc.uart2csr) # set extra constraints diff --git a/examples/de0_nano/client/test_MiLa_0.py b/examples/de0_nano/client/test_MiLa_0.py deleted file mode 100644 index 6011f742..00000000 --- a/examples/de0_nano/client/test_MiLa_0.py +++ /dev/null @@ -1,79 +0,0 @@ -from miscope import trigger, recorder, miIo, miLa -from miscope.tools.truthtable import * -from miscope.tools.vcd import * -from miscope.bridges.spi2csr.tools.uart2Spi import * - -#============================================================================== -# P A R A M E T E R S -#============================================================================== -# Bus Width -trig_width = 16 -dat_width = 16 - -# Record Size -record_size = 4096 - -# Csr Addr -MIIO_ADDR = 0x0000 -MILA_ADDR = 0x0200 - -csr = Uart2Spi(1, 115200, debug=False) - -# MiScope Configuration -# miIo0 -miIo0 = miIo.MigIo(MIIO_ADDR, 8, "IO",csr) - -# miLa0 -term0 = trigger.Term(trig_width) -trigger0 = trigger.Trigger(trig_width, [term0]) -recorder0 = recorder.Recorder(dat_width, record_size) - -miLa0 = miLa.MiLa(MILA_ADDR, trigger0, recorder0, csr) - -#============================================================================== -# T E S T M I G L A -#============================================================================== -dat_vcd = [] -recorder0.size(1024) - -def capture(size): - global trigger0 - global recorder0 - global dat_vcd - sum_tt = gen_truth_table("term0") - miLa0.trig.sum.write(sum_tt) - miLa0.rec.reset() - miLa0.rec.offset(0) - miLa0.rec.arm() - print("-Recorder [Armed]") - print("-Waiting Trigger...", end = ' ') - while(not miLa0.rec.is_done()): - time.sleep(0.1) - print("[Done]") - - print("-Receiving Data...", end = ' ') - sys.stdout.flush() - dat_vcd += miLa0.rec.read(size) - print("[Done]") - -print("Capturing Ramp..") -print("----------------------") -term0.write(0x0000,0xFFFF) -csr.write(0x0000, 0) -capture(1024) - -print("Capturing Square..") -print("----------------------") -term0.write(0x0000,0xFFFF) -csr.write(0x0000, 1) -capture(1024) - -print("Capturing Sinus..") -print("----------------------") -term0.write(0x0080,0xFFFF) -csr.write(0x0000, 2) -capture(1024) - -myvcd = Vcd() -myvcd.add(Var("wire", 16, "trig_dat", dat_vcd)) -myvcd.write("test_MiLa_0.vcd") \ No newline at end of file diff --git a/examples/de0_nano/client/test_MiLa_1.py b/examples/de0_nano/client/test_MiLa_1.py deleted file mode 100644 index 6583f17c..00000000 --- a/examples/de0_nano/client/test_MiLa_1.py +++ /dev/null @@ -1,62 +0,0 @@ -from miscope import trigger, recorder, miIo, miLa -from miscope.tools.truthtable import * -from miscope.tools.vcd import * -from miscope.bridges.spi2csr.tools.uart2Spi import * - -#============================================================================== -# P A R A M E T E R S -#============================================================================== -# Bus Width -trig_width = 32 -dat_width = 32 - -# Record Size -record_size = 4096 - -# Csr Addr -MIIO0_ADDR = 0x0000 -MILA1_ADDR = 0x0600 - -csr = Uart2Spi(1, 115200, debug=False) - -# MiScope Configuration -# miIo0 -miIo0 = miIo.MigIo(MIIO0_ADDR, 8, "IO",csr) - -# miLa1 -term1 = trigger.Term(trig_width) -trigger1 = trigger.Trigger(trig_width, [term1]) -recorder1 = recorder.Recorder(dat_width, record_size) - -miLa1 = miLa.MiLa(MILA1_ADDR, trigger1, recorder1, csr) - -#============================================================================== -# T E S T M I G L A -#============================================================================== -dat_vcd = [] -recorder1.size(1024) - -term1.write(0x0100005A,0x0100005A) -sum_tt = gen_truth_table("term1") -miLa1.trig.sum.write(sum_tt) -miLa1.rec.reset() -miLa1.rec.offset(256) -miLa1.rec.arm() - -print("-Recorder [Armed]") -print("-Waiting Trigger...", end = ' ') -csr.write(0x0000,0x5A) -while(not miLa1.rec.is_done()): - time.sleep(0.1) -print("[Done]") - -print("-Receiving Data...", end = ' ') -sys.stdout.flush() -dat_vcd += miLa1.rec.read(1024) -print("[Done]") - -myvcd = Vcd() -myvcd.add(Var("wire", 8, "csr_dat_w", get_bits(dat_vcd, 32, 0, 8))) -myvcd.add(Var("wire", 16, "csr_adr", get_bits(dat_vcd, 32, 8, 24))) -myvcd.add(Var("wire", 1, "csr_we", get_bits(dat_vcd, 32, 24))) -myvcd.write("test_MiLa_1.vcd") \ No newline at end of file diff --git a/examples/de0_nano/client/test_MiIo.py b/examples/de0_nano/client/test_miio.py similarity index 70% rename from examples/de0_nano/client/test_MiIo.py rename to examples/de0_nano/client/test_miio.py index e677aa8f..0e011923 100644 --- a/examples/de0_nano/client/test_MiIo.py +++ b/examples/de0_nano/client/test_miio.py @@ -1,44 +1,37 @@ -from miscope import trigger, recorder, miIo -from miscope.bridges.spi2csr.tools.uart2Spi import * +from miscope import miio +from miscope.bridges.uart2csr.tools.uart2Csr import * #============================================================================== # P A R A M E T E R S #============================================================================== -# Bus Width -trig_width = 16 -dat_width = 16 -# Record Size -record_size = 1024 - -csr = Uart2Spi(1,115200) +csr = Uart2Csr(3,115200) # Csr Addr MIIO_ADDR = 0x0000 # Miscope Configuration -# miIo -miIo0 = miIo.MiIo(MIIO_ADDR, 8, "IO", csr) +miio = miio.MiIo(MIIO_ADDR, 8, "IO", csr) def led_anim0(): for i in range(10): - miIo0.write(0xA5) + miio.write(0xA5) time.sleep(0.1) - miIo0.write(0x5A) + miio.write(0x5A) time.sleep(0.1) def led_anim1(): - #Led << for j in range(4): + #Led << ledData = 1 for i in range(8): - miIo0.write(ledData) + miio.write(ledData) time.sleep(i*i*0.0020) ledData = (ledData<<1) #Led >> ledData = 128 for i in range(8): - miIo0.write(ledData) + miio.write(ledData) time.sleep(i*i*0.0020) ledData = (ledData>>1) @@ -53,6 +46,4 @@ led_anim1() time.sleep(1) print("- Read Switch: ",end=' ') -print(miIo0.read()) - - +print("%02X" %miio.read()) diff --git a/examples/de0_nano/misc.py b/examples/de0_nano/misc.py new file mode 100644 index 00000000..1067a5c4 --- /dev/null +++ b/examples/de0_nano/misc.py @@ -0,0 +1,111 @@ +from migen.fhdl.structure import * +from migen.fhdl.module import Module + +class RisingEdge(Module): + def __init__(self, i=None, o=None, domain="sys"): + self.i = ifthenelse(i, i, Signal()) + self.o = ifthenelse(o, o, Signal()) + #### + i_d = Signal() + sync =[i_d.eq(self.i)] + self.comb +=[self.o.eq(self.i & ~i_d)] + self._fragment += Fragment(sync={domain : sync}) + +class FallingEdge(Module): + def __init__(self, i=None, o=None, domain="sys"): + self.i = ifthenelse(i, i, Signal()) + self.o = ifthenelse(o, o, Signal()) + #### + i_d = Signal() + sync =[i_d.eq(self.i)] + self.comb +=[self.o.eq(~self.i & i_d)] + self._fragment += Fragment(sync={domain : sync}) + +class FreqGen(Module): + def __init__(self, clk_freq, freq, o=None): + cnt_max = int(clk_freq/freq/2) + width = bits_for(cnt_max) + + self.o = ifthenelse(o, o, Signal()) + #### + cnt = Signal(width) + self.sync += [ + If(cnt >= cnt_max, + cnt.eq(0), + self.o.eq(~self.o) + ).Else( + cnt.eq(cnt+1) + ) + ] + +RISING_EDGE = 1 +FALLING_EDGE = 0 + +class EventGen(Module): + def __init__(self, i=None, level=1, clk_freq=0, length=1, o=None): + + cnt_max = int(length*clk_freq) + width = bits_for(cnt_max) + + self.i = ifthenelse(i, i, Signal()) + self.o = ifthenelse(o, o, Signal()) + ### + cnt = Signal(width) + i_edge = Signal() + + if level == RISING_EDGE: + self.submodules += RisingEdge(self.i, i_edge) + elif level == FALLING_EDGE: + self.submodules += FallingEdge(self.i, i_edge) + + self.sync += [ + If(i_edge == 1, + cnt.eq(0), + self.o.eq(1) + ).Elif(cnt >= cnt_max, + self.o.eq(0) + ).Else( + cnt.eq(cnt+1) + ), + ] + +class PwmGen(Module): + def __init__(self, width, o=None): + self.ratio = Signal(width) + self.o = ifthenelse(o, o, Signal()) + ### + cnt = Signal(width) + self.sync += [ + If(cnt == 0, + self.o.eq(1) + ).Elif(cnt >= self.ratio, + self.o.eq(0) + ), + cnt.eq(cnt+1) + ] + +class Cascade(Module): + def __init__(self, i=None, elements=None, o=None): + self.i = ifthenelse(i, i, Signal()) + self.o = ifthenelse(o, o, Signal()) + self.comb +=[elements[0].i.eq(self.i)] + self.comb +=[elements[i+1].i.eq(elements[i].o) for i in range(len(elements)-1)] + self.comb +=[self.o.eq(elements[len(elements)-1].o)] + +class PwrOnRst(Module): + def __init__(self, width, rst=None, simulation=False): + self.rst = ifthenelse(rst, rst, Signal()) + ### + cnt = Signal(width) + sync_no_reset = [If(self.rst, cnt.eq(cnt+1))] + if not simulation: + self.comb +=[ + If(cnt >= (2**width-1), + self.rst.eq(0) + ).Else( + self.rst.eq(1) + ) + ] + else: + self.comb += self.rst.eq(0) + self._fragment += Fragment(sync={"sys_no_reset" : sync_no_reset}) \ No newline at end of file diff --git a/examples/de0_nano/top.py b/examples/de0_nano/top.py index 0c171c0b..40bef128 100644 --- a/examples/de0_nano/top.py +++ b/examples/de0_nano/top.py @@ -7,8 +7,8 @@ # # Copyright 2013 / Florent Kermarrec / florent@enjoy-digital.fr # -# miscope example on De0 Nano -# --------------------------- +# miscope miio example on De0 Nano +# -------------------------------- ################################################################################ #============================================================================== @@ -27,19 +27,19 @@ from timings import * # P A R A M E T E R S #============================================================================== -#Timings Param +# Timings Param clk_freq = 50*MHz # Csr Addr MIIO0_ADDR = 0x0000 #============================================================================== -# M I S C O P E E X A M P L E +# M I S C O P E E X A M P L E #============================================================================== class SoC(Module): def __init__(self): - # migIo0 - self.submodules.miIo0 = miio.MiIo(MIIO0_ADDR, 8, "IO") + # MiIo + self.submodules.miio = miio.MiIo(MIIO0_ADDR, 8, "IO") # Uart2Csr self.submodules.uart2csr = uart2csr.Uart2Csr(clk_freq, 115200) @@ -47,11 +47,15 @@ class SoC(Module): # Csr Interconnect self.submodules.csrcon = csr.Interconnect(self.uart2csr.csr, [ - self.miIo0.bank.bus + self.miio.bank.bus ]) - self.led = Signal() - - ### - + # Led - self.comb += self.led.eq(self.miIo0.o[0]) \ No newline at end of file + self.led = Signal(8) + + ### + # Output + self.comb += self.led.eq(self.miio.o) + + # Input + self.comb += self.miio.i.eq(0x5A) \ No newline at end of file diff --git a/miscope/bridges/uart2csr/__init__.py b/miscope/bridges/uart2csr/__init__.py index f975d3b3..b10d2dff 100644 --- a/miscope/bridges/uart2csr/__init__.py +++ b/miscope/bridges/uart2csr/__init__.py @@ -38,14 +38,14 @@ class Uart2Csr(Module): addr = Signal(32) data = Signal(8) - # FSM self.submodules.fsm = FSM("IDLE", "GET_BL", "GET_ADDR", - "GET_DATA", "WRITE_CSR", - "READ_CSR", "SEND_DATA") + "GET_DATA", "WRITE_CSR", + "READ_CSR0", "READ_CSR1", "SEND_DATA") fsm = self.fsm + # # Global # @@ -53,13 +53,13 @@ class Uart2Csr(Module): If(fsm.ongoing(fsm.IDLE), cnt.eq(0) ).Elif(uart.rx_ev, cnt.eq(cnt + 1)), - sr.eq(Cat(uart.rx_dat, sr[0:24])) + If(uart.rx_ev, sr.eq(Cat(uart.rx_dat, sr[0:24]))) ] - - # State done + # State done signals get_bl_done = Signal() get_addr_done = Signal() + get_addr_done_d = Signal() get_data_done = Signal() send_data_done = Signal() @@ -72,12 +72,7 @@ class Uart2Csr(Module): ) ) - self.sync +=[ - If(fsm.ongoing(fsm.IDLE) & uart.rx_ev, - cmd.eq(uart.rx_dat) - ) - - ] + self.sync += If(fsm.ongoing(fsm.IDLE) & uart.rx_ev, cmd.eq(uart.rx_dat)) # # Get burst length @@ -90,11 +85,7 @@ class Uart2Csr(Module): self.comb += get_bl_done.eq(uart.rx_ev & fsm.ongoing(fsm.GET_BL)) - self.sync +=[ - If(get_bl_done, - burst_cnt.eq(uart.rx_dat) - ) - ] + self.sync += If(get_bl_done, burst_cnt.eq(uart.rx_dat)) # # Get address @@ -103,17 +94,18 @@ class Uart2Csr(Module): If(get_addr_done & (cmd == WRITE_CMD), fsm.next_state(fsm.GET_DATA) ).Elif(get_addr_done & (cmd == READ_CMD), - fsm.next_state(fsm.READ_CSR) + fsm.next_state(fsm.READ_CSR0) ) ) self.comb += get_addr_done.eq(uart.rx_ev & (cnt == 4) & fsm.ongoing(fsm.GET_ADDR)) + self.sync += get_addr_done_d.eq(get_addr_done) - self.sync +=[ - If(get_addr_done, + self.sync += [ + If(get_addr_done_d, addr.eq(sr) - ).Elif(get_data_done | send_data_done, - addr.eq(addr + 4) + ).Elif(fsm.leaving(fsm.WRITE_CSR) | send_data_done, + addr.eq(addr + 1) ) ] @@ -122,13 +114,12 @@ class Uart2Csr(Module): # fsm.act(fsm.GET_DATA, If(get_data_done, - fsm.next_state(fsm.IDLE) + fsm.next_state(fsm.WRITE_CSR) ) ) self.comb += get_data_done.eq(uart.rx_ev & fsm.ongoing(fsm.GET_DATA)) - - self.sync +=[ + self.sync += [ If(get_data_done, burst_cnt.eq(burst_cnt-1), data.eq(uart.rx_dat) @@ -139,46 +130,57 @@ class Uart2Csr(Module): # Write Csr # fsm.act(fsm.WRITE_CSR, - If((not burst_cnt), + If((burst_cnt==0), fsm.next_state(fsm.IDLE) ).Else(fsm.next_state(fsm.GET_DATA)) ) + + # + # Read Csr0 + # + fsm.act(fsm.READ_CSR0, + fsm.next_state(fsm.READ_CSR1) + ) + + self.sync += If(fsm.entering(fsm.READ_CSR0), burst_cnt.eq(burst_cnt-1)) + # - # Read Csr + # Read Csr1 # - fsm.act(fsm.READ_CSR, + fsm.act(fsm.READ_CSR1, fsm.next_state(fsm.SEND_DATA) ) + # # Send Data # fsm.act(fsm.SEND_DATA, - If(send_data_done & (not burst_cnt), + If(send_data_done & (burst_cnt==0), fsm.next_state(fsm.IDLE) ).Elif(send_data_done, - fsm.next_state(fsm.READ_CSR) + fsm.next_state(fsm.READ_CSR0) ) ) - self.comb += [ + self.comb += send_data_done.eq(fsm.ongoing(fsm.SEND_DATA) & uart.tx_ev) + + self.sync += [ uart.tx_dat.eq(self.csr.dat_r), uart.tx_we.eq(fsm.entering(fsm.SEND_DATA)), - send_data_done.eq(~uart.tx_we | uart.tx_ev) ] + # # Csr access # + self.comb += self.csr.adr.eq(addr) self.sync +=[ - self.csr.adr.eq(addr), self.csr.dat_w.eq(data), If(fsm.ongoing(fsm.WRITE_CSR), self.csr.we.eq(1) ).Else( self.csr.we.eq(0) ) - ] - - + ] \ No newline at end of file diff --git a/miscope/bridges/uart2csr/tools/__init__.py b/miscope/bridges/uart2csr/tools/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/miscope/bridges/uart2csr/tools/uart2Csr.py b/miscope/bridges/uart2csr/tools/uart2Csr.py new file mode 100644 index 00000000..0f265eb8 --- /dev/null +++ b/miscope/bridges/uart2csr/tools/uart2Csr.py @@ -0,0 +1,59 @@ +import string +import time +import serial +from struct import * +import time + +WRITE_CMD = 0x01 +READ_CMD = 0x02 +CLOSE_CMD = 0x03 + +def write_b(uart, data): + uart.write(pack('B',data)) + +class Uart2Csr: + def __init__(self, port, baudrate, debug=False): + self.port = port + self.baudrate = baudrate + self.debug = debug + self.uart = serial.Serial(port, baudrate, timeout=0.25) + + def read(self, addr, burst_length=1): + write_b(self.uart, READ_CMD) + write_b(self.uart, burst_length) + write_b(self.uart, (addr & 0xff000000) >> 24) + write_b(self.uart, (addr & 0x00ff0000) >> 16) + write_b(self.uart, (addr & 0x0000ff00) >> 8) + write_b(self.uart, (addr & 0x000000ff)) + values = [] + for i in range(burst_length): + read = self.uart.read(1) + val = int(read[0]) + if self.debug: + print("RD %02X @ %08X" %(val, addr + 4*i)) + values.append(val) + if burst_length == 1: + return values[0] + else: + return values + + def write(self, addr, data): + if isinstance(data, list): + burst_length = len(data) + else: + burst_length = 1 + write_b(self.uart, WRITE_CMD) + write_b(self.uart, burst_length) + self.uart.write([(addr & 0xff000000) >> 24, + (addr & 0x00ff0000) >> 16, + (addr & 0x0000ff00) >> 8, + (addr & 0x000000ff)]) + if isinstance(data, list): + for i in range(len(data)): + write_b(self.uart, data[i]) + if self.debug: + print("WR %02X @ %08X" %(elt, addr + 4*i)) + else: + write_b(self.uart, data) + if self.debug: + print("WR %02X @ %08X" %(data, addr)) \ No newline at end of file diff --git a/miscope/bridges/uart2csr/uart.py b/miscope/bridges/uart2csr/uart.py index f344e1a7..12d46c37 100644 --- a/miscope/bridges/uart2csr/uart.py +++ b/miscope/bridges/uart2csr/uart.py @@ -18,6 +18,7 @@ class UART(Module): self.tx = Signal(reset=1) self.rx = Signal() + ### @@ -34,8 +35,10 @@ class UART(Module): tx_reg = Signal(8) tx_bitcount = Signal(4) tx_count16 = Signal(4) - tx_busy = self.tx_ev + tx_done = self.tx_ev + tx_busy = Signal() self.sync += [ + tx_done.eq(0), If(self.tx_we, tx_reg.eq(self.tx_dat), tx_bitcount.eq(0), @@ -50,7 +53,8 @@ class UART(Module): self.tx.eq(1) ).Elif(tx_bitcount == 9, self.tx.eq(1), - tx_busy.eq(0) + tx_busy.eq(0), + tx_done.eq(1) ).Else( self.tx.eq(tx_reg[0]), tx_reg.eq(Cat(tx_reg[1:], 0)) diff --git a/miscope/miio.py b/miscope/miio.py index 38a9b7c9..bad8dbc4 100644 --- a/miscope/miio.py +++ b/miscope/miio.py @@ -38,8 +38,7 @@ class MiIo: #Driver # def write(self, data): - self.interface.write(self.address, data, self.width) + self.interface.write(self.address, data) def read(self): - r = self.interface.read(self.address + self.words, self.width) - return r \ No newline at end of file + return self.interface.read(self.address + self.words) \ No newline at end of file -- 2.30.2