MyHDL experiments http://www.myhdl.org/ Entry: toVerilog / toVHDL Date: Thu Feb 4 13:13:50 EST 2016 toVerilog(Module, *signals) For simulation, the arguments of a module can be any Python object, but for conversion to VHDL or Verilog these need to be signals. Also, the @always_comb seems to produce a process/always block. Why not an RTL / dataflow block? Entry: How does translation work? Date: Thu Feb 4 13:46:53 EST 2016 in myhdl/myhdl/conversion/_analyze.py the following modules are imported: https://docs.python.org/3/library/inspect.html https://docs.python.org/3/library/ast.html A Visitor over AST is used, so looks like this maps python syntax to VHDL, not "probing" of objects. To meta-program this, it would be necessary to generate python code, not just python objects. Entry: Lists of signals to/from signals of lists Date: Mon Apr 25 10:30:33 EDT 2016 It would help to be a bit more clear about the data types. As I understand, Signal adds sensitivity to a thing, but a sliced Signal of an intbv is not a Signal of an intbv. See next post. This describes 'ConcatSignal' and the generic list<->intbv problem. http://docs.myhdl.org/en/stable/manual/structure.html#converting-between-lists-of-signals-and-bit-vectors Entry: iCEblink40 + tools on linux Date: Mon Apr 25 15:02:31 EDT 2016 http://www.soerenbnoergaard.dk/project_ice40_archlinux.html https://github.com/reactive-systems/icedude (icedude is in haskell!) Entry: What is a Signal? Date: Mon Apr 25 18:08:39 EDT 2016 Looking at the code, a Signal implements some behaviors: - integer operations, indexing delegated to ._val which is one of: - bool - integer_types (int, long) - intbv - EnumItemType - update propagation (event waiters) - shadow signals (joining multiple signals into one) Entry: Misconceptions and Quirks Date: Tue Apr 26 17:25:18 EDT 2016 M: Cannot use arrays of interfaces as a parameter to a primitive generator. The "type error" here is that interfaces are for structural modeling. Q: Can't have instances in lists that get collected? It confuses hierarchy extraction. Workaround: use list.append() Should be fixed by using @block M: What is the relation between python blocks and generators, and the resulting VHDL? Parameters should correspond. I get garbage. Maybe arrays of interfaces are not supported? M: It is possible to represent a list of interfaces as an interface of bit vectors. M: It is possible to collect signals in a list, and iterate over that list to perform assignments. M: I miss plain and simple functions inside @always_comb generator definitions. It seems this doesn't work, and needs to be solved at structural level through instantiation. M: vec(1) vs vec[1] ? Entry: Interfaces Date: Tue Apr 26 21:29:09 EDT 2016 http://stackoverflow.com/questions/21087314/how-to-implement-interfaces-in-myhdl http://dev.myhdl.org/meps/mep-107.html http://www.edaplayground.com/s/130/941 Entry: Transposing & Muxing Date: Wed Apr 27 12:06:35 EDT 2016 Problem: the bits of a vector are selected based on a bit. I'd like to express this as an indexing operation, but that doesn't seem to work because the resulting vector can't be written at once. Entry: WTF Date: Wed Apr 27 20:58:39 EDT 2016 This really has too much magic going on. I get a bugs in signal names (None) which get propagated into the Verilog. I'm guessing this has to do with the doubly nested lists. How do signals get their names? Entry: Avoiding interfaces Date: Wed Apr 27 21:16:40 EDT 2016 Maybe it is better to avoid interfaces alltogether, and use explicit port naming at the top level, then gather these in lists in the instantiation. EDIT: got it to work following examples in [1]. Basic ideas: - Keep the toplevel flat. This gives most control over pin names, as those need to be added to the pin constraint file in iCE40 tools. - Keep the toplevel stupid: only perform connection there. Since the interface is flat, this code will look flat as well. But at this point it is possible to put the top level ports in lists or interfaces. - Inner blocks and generators are not hindered by limitations of the top level ports. - When creating lists of signals, use only flat lists, and be sure to assign those lists to a local variable. Hierarchy analysis uses those names, but doesn't raise errors when "None" appears in the target HDL code. Structural modeling isn't completely unconstrained Python! [1] https://github.com/cfelton/minnesota Entry: iCEblink40 pcf Date: Thu Apr 28 16:01:55 EDT 2016 ################################# # iCEblink40 LP1K Demonstration Design # Family & Device: iCE40LP1K # Package: QN84 ################################# ###IOSet List 22 # Capacitive-sense buttons set_io BTN1 B22 -pullup yes set_io BTN2 B21 -pullup yes set_io BTN3 A27 -pullup yes set_io BTN4 A26 -pullup yes # LED outputs set_io LED1 A29 set_io LED2 B20 set_io LED3 B19 set_io LED4 A25 # 3.3 MHz clock input set_io CLK_3P3_MHZ A9 # Digilent ADEPT2 USB interface set_io ASTB A12 set_io DB[0] A20 set_io DB[1] B15 set_io DB[2] A19 set_io DB[3] B14 set_io DB[4] B13 set_io DB[5] B12 set_io DB[6] B11 set_io DB[7] B10 set_io DSTB A13 set_io WAIT A16 set_io WRITE A14 # SPI Flash enable control set_io SS_B B18 Entry: iCEblink40 Digilent ADEPT2 / iCEDude Date: Thu Apr 28 16:02:13 EDT 2016 https://github.com/reactive-systems/icedude That 8-bit interface might be quite useful to get a 3-instruction forth running. Entry: icestorm Date: Fri Apr 29 23:14:30 EDT 2016 http://www.clifford.at/icestorm/ Entry: Lattice iCEcube2 licence Date: Sat May 28 11:10:14 EDT 2016 http://www.latticesemi.com/Support/Licensing/DiamondAndiCEcube2SoftwareLicensing/iceCube2.aspx Entry: single-ended if Date: Sun Jun 19 12:01:50 EDT 2016 Interesting because it allows state update in a more concise way, as opposed to "full branch" if which is combinatorial / functional. Hard to express exactly what I mean but basically: single ended if updates a register if a certain condition is met, but leaves the register at its previous value otherwise. Entry: edges Date: Mon Jun 20 14:12:54 EDT 2016 I'm still not clear on semantics of time - off by one? For an assignment to .next during: @always_seq(p.FPGA_CLK.posedge) is that change-of-value supposed to happen at this posedge, or the next one? Say a.next = b when are a and b valid? The semantics of ".next" is derived from the operational semantics of the discrete event simulator. The map to HDL then implements a similar behavior using FFs. For combinatorial logic: - a.next = b really means: a = b (minus some propagation delay) this is why there is no feedback allowed For sequential logic: - a.next = b really means: the input of the d-ff (a.next) is set to b, which can be derived combinatorially from the output of the d-ff To remember: printing out signals, only ever print out the "now" values, not the .next values, because the order in which the updates are run is not specified. Still it is confusing to work with this. Maybe to perform test readouts, always do them in a clock-sensitive process, instead of manually trying to guess where things are at from the stim process? Entry: Reading from a tristate signal Date: Sun Jul 24 17:16:50 EDT 2016 Produces None in the MyHDL Simulation if it wasn't driven before. Because initial value is None, this fails when trying to assign the value to another signal. Also arachne-pnr has problems. ( ATM I can't get lattice tools to infer RAM so sticking to yosys/arachne-pnr for now ) Maybe it's best to avoid the whole thing by manually instantiate as mentioned here? https://github.com/cseed/arachne-pnr/issues/24 SB_IO #( .PIN_TYPE(6'b 1010_01), .PULLUP(1'b 0) ) led_io ( .PACKAGE_PIN(LED5), .OUTPUT_ENABLE(outcnt[0]), .D_OUT_0(outcnt[1]), .D_IN_0(dummy) ); Then to use MyHDL, maybe leave the toplevel file as verilog, and instantiate separate modules? That would give a patch point to add any other workarounds. Maybe the same can be done with the RAM. First, syntax: SB is short for SilliconBlue, before bought by Lattice. SB_IO is the module name. #() are constant parameters? led_io is the instance name () are module parameters .param(signal) http://electronics.stackexchange.com/questions/24316/how-do-i-define-a-module-with-a-modified-parameter-in-verilog module-name #(parameter-assignment) instance-name (module-terminal-list) ; Entry: synchronous reset Date: Fri Jul 29 12:28:38 EDT 2016 A particularly convenient pattern is to use a ResetSignal as a state machine start signal. When reset is released, the machine runs until its halt state is reached. But if this reset signals is synchronous to the clock, is there a caveat to use ResetSignal as sync or async? Entry: yosys circuit Date: Fri Jul 29 23:33:53 EDT 2016 http://www.clifford.at/yosys/files/yosys_appnote_011_design_investigation.pdf Entry: clock buffers Date: Mon Aug 8 12:52:27 EDT 2016 While yosys says GBs / GB_IOs is 0, it is actually arachne-pnr that will infer clock buffers during routing. https://github.com/cliffordwolf/yosys/issues/107 promote_globals... promoted FPGA_CLK$2, 162 / 162 promoted FPGA_RESET$2, 86 / 86 promoted SPI2_SCLK$2, 53 / 55 promoted $abc$11948$n3, 43 / 43 promoted spi_cmd_inst_r_nss, 37 / 37 promoted dti_in_multi_inst_dti_in_inst_1_cinst_dti_framer_circuit_spiClk, 23 / 23 promoted dti_in_multi_inst_dti_in_inst_0_cinst_dti_framer_circuit_spiClk, 23 / 23 promoted $abc$11948$n475, 18 / 18 promoted 8 nets 3 sr/we 1 cen/wclke 4 clk 8 globals 3 sr/we 1 cen/wclke 4 clk Entry: ice40 block ram Date: Mon Aug 8 14:27:26 EDT 2016 Might need large setup time, e.g. might not be possible to clock from machine that produces the data at the same edge as the write pulse? Can't find t_SUADDR_EBR. Actually I tried this for data and strobe generated from same clock. Entry: Clock from timer: problems Date: Mon Aug 8 17:06:21 EDT 2016 FPGA clock derived from 36MHz timer output of uC. Problem is that all other signals will change at the same time as one of the edges, likely leading to hold time violation. If I/O bus is at 36MHz, then one of these edges is going to be OK. Entry: forking generators Date: Fri Aug 12 19:35:48 EDT 2016 http://docs.myhdl.org/en/stable/manual/reference.html yield: Furthermore, MyHDL generators can be used as clauses in yield statements. Such a generator is forked, and starts operating immediately, while the original generator waits for it to complete. The original generator resumes when the forked generator returns. So it is possible to do arbitrary deep procedure calls inside a generator. Good thing. Entry: concat and shadow signals Date: Sun Jun 10 15:43:55 EDT 2018 What's the difference between creating a new signal and using "concat", vs creating a shadow signal? Eventually, if the signals are combinatorial, the output should be the same. I.e. just wires. Entry: Intermediate nodes Date: Mon Jun 11 10:42:13 EDT 2018 It seems possible to have intermediate nodes that are not signals. E.g. these two constructs are seen in the wild: a = Signal(intbv(...)) a = intbv(...) I think I need the naked ones in my code generator to implement intermediate combinatorial nodes that have fanout. EDIT: After reading the manual, it appears that the intbv object is a value, while the Signal behaves more like a cell (+ synchronization).