myhdl-list Mailing List for MyHDL (Page 104)
Brought to you by:
jandecaluwe
You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(14) |
Nov
(4) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(1) |
Feb
(10) |
Mar
(19) |
Apr
(14) |
May
(1) |
Jun
(4) |
Jul
(10) |
Aug
|
Sep
(2) |
Oct
(7) |
Nov
(17) |
Dec
(12) |
2005 |
Jan
(6) |
Feb
(10) |
Mar
(17) |
Apr
(10) |
May
(9) |
Jun
(5) |
Jul
(26) |
Aug
(34) |
Sep
(10) |
Oct
(38) |
Nov
(71) |
Dec
(74) |
2006 |
Jan
(20) |
Feb
(20) |
Mar
(7) |
Apr
(2) |
May
(13) |
Jun
|
Jul
|
Aug
(4) |
Sep
(37) |
Oct
(43) |
Nov
(30) |
Dec
(33) |
2007 |
Jan
(3) |
Feb
|
Mar
|
Apr
|
May
(30) |
Jun
(9) |
Jul
(1) |
Aug
|
Sep
(8) |
Oct
(13) |
Nov
|
Dec
(4) |
2008 |
Jan
(13) |
Feb
(46) |
Mar
(25) |
Apr
(7) |
May
(20) |
Jun
(73) |
Jul
(38) |
Aug
(47) |
Sep
(24) |
Oct
(18) |
Nov
(9) |
Dec
(36) |
2009 |
Jan
(31) |
Feb
(24) |
Mar
(73) |
Apr
(13) |
May
(47) |
Jun
(28) |
Jul
(36) |
Aug
(2) |
Sep
(5) |
Oct
(8) |
Nov
(16) |
Dec
(29) |
2010 |
Jan
(34) |
Feb
(18) |
Mar
(18) |
Apr
(5) |
May
|
Jun
(24) |
Jul
(53) |
Aug
(3) |
Sep
(18) |
Oct
(33) |
Nov
(19) |
Dec
(15) |
2011 |
Jan
(9) |
Feb
(4) |
Mar
(39) |
Apr
(213) |
May
(86) |
Jun
(46) |
Jul
(22) |
Aug
(11) |
Sep
(78) |
Oct
(59) |
Nov
(38) |
Dec
(24) |
2012 |
Jan
(9) |
Feb
(22) |
Mar
(89) |
Apr
(55) |
May
(222) |
Jun
(86) |
Jul
(57) |
Aug
(32) |
Sep
(49) |
Oct
(69) |
Nov
(12) |
Dec
(35) |
2013 |
Jan
(67) |
Feb
(39) |
Mar
(18) |
Apr
(42) |
May
(79) |
Jun
(1) |
Jul
(19) |
Aug
(18) |
Sep
(54) |
Oct
(79) |
Nov
(9) |
Dec
(26) |
2014 |
Jan
(30) |
Feb
(44) |
Mar
(26) |
Apr
(11) |
May
(39) |
Jun
(1) |
Jul
(89) |
Aug
(15) |
Sep
(7) |
Oct
(6) |
Nov
(20) |
Dec
(27) |
2015 |
Jan
(107) |
Feb
(106) |
Mar
(130) |
Apr
(90) |
May
(147) |
Jun
(28) |
Jul
(53) |
Aug
(16) |
Sep
(23) |
Oct
(7) |
Nov
|
Dec
(16) |
2016 |
Jan
(86) |
Feb
(41) |
Mar
(38) |
Apr
(31) |
May
(37) |
Jun
(11) |
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(1) |
Nov
(5) |
Dec
(3) |
2017 |
Jan
|
Feb
(4) |
Mar
(2) |
Apr
(2) |
May
|
Jun
(3) |
Jul
(2) |
Aug
(2) |
Sep
(1) |
Oct
(2) |
Nov
(1) |
Dec
(1) |
2018 |
Jan
(1) |
Feb
(1) |
Mar
(7) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2019 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
(1) |
May
(1) |
Jun
(2) |
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
(3) |
Dec
|
2020 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(1) |
Oct
|
Nov
|
Dec
(3) |
2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
(12) |
Dec
(11) |
2022 |
Jan
(7) |
Feb
(2) |
Mar
(1) |
Apr
|
May
|
Jun
(1) |
Jul
(3) |
Aug
(2) |
Sep
(1) |
Oct
|
Nov
|
Dec
(1) |
2023 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
(3) |
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2024 |
Jan
(1) |
Feb
(2) |
Mar
(4) |
Apr
(2) |
May
(2) |
Jun
(1) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
|
Nov
|
Dec
(2) |
2025 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: David K. <dav...@in...> - 2011-12-22 13:31:56
|
I am puzzled by traceSignals() generating 'Inconsistent hierarchy' messages with the following code, but not if badBehaviour is False. Note that the print at line 32 gives the same structure in both cases, so its something I don't understand in the introspection. I wanted to structure a collection of tests using a common library, and this (bad) behaviour gets in the way of a natural expression of reuse. Example: #!/usr/bin/python # example of strange behaviour in traceSignals() badBehaviour = True from myhdl import * def ClkDriver(clk, halfperiod=5): halfPeriod = delay(halfperiod) @always(halfPeriod) def driveClk(): clk.next = 1 & ~clk return driveClk def device_test(clk1, cd1): clk2 = Signal(0) cd2 = ClkDriver(clk2, halfperiod=3759) # in picoseconds to give 7.5ns(133MHz) cycle if badBehaviour: return (cd2,) else: return cd1, cd2 def test(): # make a clock generator clk1 = Signal(0) cd1 = ClkDriver(clk1, halfperiod=3759) # in picoseconds to give 7.5ns(133MHz) cycle if badBehaviour: ret = (cd1,) + device_test(clk1, cd1) else: ret = device_test(clk1, cd1) print ret return ret def process(timesteps): # wrap in a tracer for vcd output tr_out = traceSignals(test) # simulate sim = Simulation(tr_out) sim.run(timesteps) if __name__ == '__main__': timesteps = 1000 process(timesteps) Dave Kitchen |
From: Oscar D. <osc...@gm...> - 2011-12-20 13:55:12
|
2011/12/20 Christopher Felton <chr...@gm...>: > On 12/20/2011 5:35 AM, Oscar Diaz wrote: >> Hi >> >> I have a testbench that needs to do some asserts at the end of a >> simulation. However, I couldn't find an elegant way to do it. Right >> now I'm passing to the testbench generator the same duration as in >> "Simulation.run(duration)" , so I can do a "yield delay(duration-1)" >> and do the final asserts (by the way, in my case all my simulations >> have a defined duration). I tried to catch the StopSimulation >> exception, but it doesn't work inside a generator. Any ideas? Thanks! >> >> Best regards >> > > I believe you can catch exceptions in generators. At least the > generator PEP says so and the following works. > > ~~~ [Code Snip] ~~~ > from myhdl import * > def test(): > @instance > def ex_in_g(): > try: > for ii in xrange(10): > yield delay(7) > raise StopSimulation > > except Exception, e: > print("Caught exception %s" % (str(e))) > raise StopSimulation > > return ex_in_g > > if __name__ == '__main__': > Simulation(test()).run() > ~~~~~~~~~~~~~~~~~~~~~~~ That's the case when the exception is raised inside the generator, which is not my case. I'm trying to something like this: ~~~ [Code Snip] ~~~ from myhdl import * def test(): @instance def ex_in_g(): try: for ii in xrange(10): yield delay(7) # ideally it shouldn't got here return except Exception, e: # or maybe better "except StopSimulation" ? print("Caught exception %s" % (str(e))) raise StopSimulation return ex_in_g if __name__ == '__main__': # fixed simulation time Simulation(test()).run(50) ~~~~~~~~~~~~~~~~~~~~~~~ It doesn't work because the exception is raised inside the run() method. Right now my project store the simulation duration to yield before raising StopSimulation, like this: ~~~ [Code Snip] ~~~ from myhdl import * sim_duration = 100 def test(): @instance def main_block(): # do some stuff return @instance def last_check(): yield delay(sim_duration - 1) print "do some final asserts..." return return instances() if __name__ == '__main__': Simulation(test()).run(sim_duration) ~~~~~~~~~~~~~~~~~~~~~~~ Any ideas to improve this issue? Best regards > > Regards, > Chris > > > ------------------------------------------------------------------------------ > Write once. Port to many. > Get the SDK and tools to simplify cross-platform app development. Create > new or port existing apps to sell to consumers worldwide. Explore the > Intel AppUpSM program developer opportunity. appdeveloper.intel.com/join > http://p.sf.net/sfu/intel-appdev > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list -- Oscar Díaz Key Fingerprint = 904B 306C C3C2 7487 650B BFAC EDA2 B702 90E9 9964 gpg --keyserver subkeys.pgp.net --recv-keys 90E99964 I recommend using OpenDocument Format for daily use and exchange of documents. http://www.fsf.org/campaigns/opendocument |
From: Christopher F. <chr...@gm...> - 2011-12-20 13:17:28
|
On 12/20/2011 5:35 AM, Oscar Diaz wrote: > Hi > > I have a testbench that needs to do some asserts at the end of a > simulation. However, I couldn't find an elegant way to do it. Right > now I'm passing to the testbench generator the same duration as in > "Simulation.run(duration)" , so I can do a "yield delay(duration-1)" > and do the final asserts (by the way, in my case all my simulations > have a defined duration). I tried to catch the StopSimulation > exception, but it doesn't work inside a generator. Any ideas? Thanks! > > Best regards > I believe you can catch exceptions in generators. At least the generator PEP says so and the following works. ~~~ [Code Snip] ~~~ from myhdl import * def test(): @instance def ex_in_g(): try: for ii in xrange(10): yield delay(7) raise StopSimulation except Exception, e: print("Caught exception %s" % (str(e))) raise StopSimulation return ex_in_g if __name__ == '__main__': Simulation(test()).run() ~~~~~~~~~~~~~~~~~~~~~~~ Regards, Chris |
From: Oscar D. <osc...@gm...> - 2011-12-20 11:35:47
|
Hi I have a testbench that needs to do some asserts at the end of a simulation. However, I couldn't find an elegant way to do it. Right now I'm passing to the testbench generator the same duration as in "Simulation.run(duration)" , so I can do a "yield delay(duration-1)" and do the final asserts (by the way, in my case all my simulations have a defined duration). I tried to catch the StopSimulation exception, but it doesn't work inside a generator. Any ideas? Thanks! Best regards -- Oscar Díaz Key Fingerprint = 904B 306C C3C2 7487 650B BFAC EDA2 B702 90E9 9964 gpg --keyserver subkeys.pgp.net --recv-keys 90E99964 I recommend using OpenDocument Format for daily use and exchange of documents. http://www.fsf.org/campaigns/opendocument |
From: Sébastien B. <seb...@mi...> - 2011-12-20 10:22:01
|
Migen (Milkymist Generator) a Python toolbox for building complex digital hardware ====================================================== Background ========== Even though the Milkymist system-on-chip [1] is technically successful, it suffers from several limitations stemming from its implementation in manually written Verilog HDL: (1) The "event-driven" paradigm of today's dominant hardware descriptions languages (Verilog and VHDL, collectively referred to as "V*HDL" in the rest of this document) is often too general. Today's FPGA architectures are optimized for the implementation of fully synchronous circuits. This means that the bulk of the code for an efficient FPGA design falls into three categories: (a) Combinatorial statements (b) Synchronous statements (c) Initialization of registers at reset V*HDL do not follow this organization. This means that a lot of repetitive manual coding is needed, which brings sources of human errors, petty issues, and confusion for beginners: - wire vs. reg in Verilog - forgetting to initialize a register at reset - deciding whether a combinatorial statement must go into a process/always block or not - simulation mismatches with combinatorial processes/always blocks - and more... A little-known fact about FPGAs is that many of them have to ability to initialize their registers from the bitstream contents. This can be done in a portable and standard way using an "initial" block in Verilog, and by affecting a value at the signal declaration in VHDL. This renders an explicit reset signal unnecessary in practice in some cases, which opens the way for further design optimization. However, this form of initialization is entirely not synthesizable for ASIC targets, and it is not easy to switch between the two forms of reset using V*HDL. (2) V*HDL support for composite types is very limited. Signals having a record type in VHDL are unidirectional, which makes them clumsy to use e.g. in bus interfaces. There is no record type support in Verilog, which means that a lot of copy-and-paste has to be done when forwarding grouped signals. (3) V*HDL support for procedurally generated logic is extremely limited. The most advanced forms of procedural generation of synthesizable logic that V*HDL offers are CPP-style directives in Verilog, combinatorial functions, and generate statements. Nothing really fancy, and it shows. To give a few examples: - Building highly flexible bus interconnect is not possible. Even arbitrating any given number of bus masters for commonplace protocols such as Wishbone cannot be done with the tools at V*HDL puts at our disposal. This requires manual recoding of parts of the arbiter to add or remove a master, which is tedious and often cause frustrating errors. Each occurence of the latter can easily cause one or two hours of lost productivity when combined with the long compilation times of moderately complex system-on-chip designs. - Building a memory infrastructure (including bus interconnect, bridges and caches) that can automatically adapt itself at compile-time to any word size of the SDRAM is clumsy and tedious. - Building register banks for control, status and interrupt management of cores can also largely benefit from automation. - Many hardware acceleration problems can fit into the dataflow programming model. Manual dataflow implementation in V*HDL has, again, a lot of redundancy and potential for human errors. See the Milkymist texture mapping unit [3][4] for an example of this. The amount of detail to deal with manually also makes the design space exploration difficult, and therefore hinders the design of efficient architectures. - Pre-computation of values, such as filter coefficients for DSP or even simply trigonometric tables, must often be done using external tools whose results are copy-and-pasted (in the best cases, automatically) into the V*HDL source. Enter Migen, a Python toolbox for building complex digital hardware. We could have designed a brand new programming language, but that would have been reinventing the wheel instead of being able to benefit from Python's rich features and immense library. The price to pay is a slightly cluttered syntax at times when writing descriptions in FHDL, but we believe this is totally acceptable, particularly when compared to VHDL ;-) Migen is made up of several related components, which are briefly described below. Migen FHDL ========== The Fragmented Hardware Description Language (FHDL) is the lowest layer of Migen. It consists of a formal system to describe signals, and combinatorial and synchronous statements operating on them. The formal system itself is low level and close to the synthesizable subset of Verilog, and we then rely on Python algorithms to build complex structures by combining FHDL elements and encapsulating them in "fragments". The FHDL module also contains a back-end to produce synthesizable Verilog, and some basic analysis functions. It would be possible to develop a VHDL back-end as well, though more difficult than for Verilog - we are "cheating" a bit now as Verilog provides most of the FHDL semantics. FHDL differs from MyHDL [2] in fundamental ways. MyHDL follows the event-driven paradigm of traditional HDLs (see Background, #1) while FHDL separates the code into combinatorial statements, synchronous statements, and reset values. In MyHDL, the logic is described directly in the Python AST. The converter to Verilog or VHDL then examines the Python AST and recognizes a subset of Python that it translates into V*HDL statements. This seriously impedes the capability of MyHDL to generate logic procedurally. With FHDL, you manipulate a custom AST from Python, and you can more easily design algorithms that operate on it. FHDL is made of several elements, which are briefly explained below. BV -- The bit vector (BV) object defines if a constant or signal is signed or unsigned, and how many bits it has. This is useful e.g. to: - determine when to perform sign extension (FHDL uses the same rules as Verilog). - determine the size of registers. - determine how many bits should be used by each value in concatenations. Constant -------- This object should be self-explanatory. All constant objects contain a BV object and a value. If no BV object is specified, one will be made up using the following rules: - If the value is positive, the BV is unsigned and has the minimum number of bits needed to represent the constant's value in the canonical base-2 system. - If the value is negative, the BV is signed, and has the minimum number of bits needed to represent the constant's value in the canonical two's complement, base-2 system. Signal ------ The signal object represents a value that is expected to change in the circuit. It does exactly what Verilog's "wire" and "reg" and VHDL's "signal" and "variable" do. The main point of the signal object is that it is identified by its Python ID (as returned by the id() function), and nothing else. It is the responsibility of the V*HDL back-end to establish an injective mapping between Python IDs and the V*HDL namespace. It should perform name mangling to ensure this. The consequence of this is that signal objects can safely become members of arbitrary Python classes, or be passed as parameters to functions or methods that generate logic involving them. The properties of a signal object are: - a bit vector description - a name, used as a hint for the V*HDL back-end name mangler. - a boolean "variable". If true, the signal will behave like a VHDL variable, or a Verilog reg that uses blocking assignment. This parameter only has an effect when the signal's value is modified in a synchronous statement. - the signal's reset value. It must be an integer, and defaults to 0. When the signal's value is modified with a synchronous statement, the reset value is the initialization value of the associated register. When the signal is assigned to in a conditional combinatorial statement (If or Case), the reset value is the value that the signal has when no condition that causes the signal to be driven is verified. This enforces the absence of latches in designs. If the signal is permanently driven using a combinatorial statement, the reset value has no effect. The sole purpose of the name property is to make the generated V*HDL code easier to understand and debug. From a purely functional point of view, it is perfectly OK to have several signals with the same name property. The back-end will generate a unique name for each object. If no name property is specified, Migen will analyze the code that created the signal object, and try to extract the variable or member name from there. It then uses the module name that created the signal, a underscore, and the variable name. For example, if we are in module "foo", the following statements will create one or several signal(s) named "foo_bar": bar = Signal() self.bar = Signal() self.baz.bar = Signal() bar = [Signal() for x in range(42)] Operators --------- Operators are represented by the _Operator object, which generally should not be used directly. Instead, most FHDL objects overload the usual Python logic and arithmetic operators, which allows a much lighter syntax to be used. For example, the expression: a * b + c is equivalent to: _Operator('+', [_Operator('*', [a, b]), c]) Slices ------ Likewise, slices are represented by the _Slice object, which often should not be used in favor of the Python slice operation [x:y]. Implicit indices using the forms [x], [x:] and [:y] are supported. Beware! Slices work like Python slices, not like VHDL or Verilog slices. The first bound is the index of the LSB and is inclusive. The second bound is the index of MSB and is exclusive. In V*HDL, bounds are MSB:LSB and both are inclusive. Concatenations -------------- Concatenations are done using the Cat object. To make the syntax lighter, its constructor takes a variable number of arguments, which are the signals to be concatenated together (you can use the Python '*' operator to pass a list instead). To be consistent with slices, the first signal is connected to the bits with the lowest indices in the result. This is the opposite of the way the '{}' construct works in Verilog. Replications ------------ The Replicate object represents the equivalent of {count{expression}} in Verilog. Assignments ----------- Assignments are represented with the _Assign object. Since using it directly would result in a cluttered syntax, the preferred technique for assignments is to use the be() method provided by objects that can have a value assigned to them. They are signals, and their combinations with the slice and concatenation operators. As an example, the statement: a[0].be(b) is equivalent to: _Assign(_Slice(a, 0, 1), b) If statement ------------ The If object takes a first parameter which must be an expression (combination of the Constant, Signal, _Operator, _Slice, etc. objects) representing the condition, then a variable number of parameters representing the statements (_Assign, If, Case, etc. objects) to be executed when the condition is verified. The If object defines a Else() method, which when called defines the statements to be executed when the condition is not true. Those statements are passed as parameters to the variadic method. For convenience, there is also a Elif() method. Example: If(tx_count16 == 0, tx_bitcount.be(tx_bitcount + 1), If(tx_bitcount == 8, self.tx.be(1) ).Elif(tx_bitcount == 9, self.tx.be(1), tx_busy.be(0) ).Else( self.tx.be(tx_reg[0]), tx_reg.be(Cat(tx_reg[1:], 0)) ) ) Case statement -------------- The Case object constructor takes as first parameter the expression to be tested, then a variable number of lists describing the various cases. Each list contains an expression (typically a constant) describing the value to be matched, followed by the statements to be executed when there is a match. The head of the list can be the an instance of the Default object. Instances --------- Instance objects represent the parametrized instantiation of a V*HDL module, and the connection of its ports to FHDL signals. They are useful in a number of cases: - reusing legacy or third-party V*HDL code. - using special FPGA features (DCM, ICAP, ...). - implementing logic that cannot be expressed with FHDL (asynchronous circuits, ...). - breaking down a Migen system into multiple sub-systems, possibly using different clock domains. The properties of the instance object are: - the type of the instance (i.e. name of the instantiated module). - a list of output ports of the instantiated module. Each element of the list is a pair containing a string, which is the name of the module's port, and either an existing signal (on which the port will be connected to) or a BV (which will cause the creation of a new signal). - a list of input ports (likewise). - a list of (name, value) pairs for the parameters ("generics" in VHDL) of the module. - the name of the clock port of the module (if any). If this is specified, the port will be connected to the system clock. - the name of the reset port of the module (likewise). - the name of the instance (can be mangled like signal names). Memories -------- Memories (on-chip SRAM) are not supported, but will be soon, using a mechanism similar to instances. (TODO) Fragments --------- A "fragment" is a unit of logic, which is composed of: - a list of combinatorial statements. - a list of synchronous statements. - a list of instances. - a list of memories. - a set of pads, which are signals intended to be connected to off-chip devices. Fragments can reference arbitrary signals, including signals that are referenced in other fragments. Fragments can be combined using the "+" operator, which returns a new fragment containing the concatenation of each pair of lists. Fragments can be passed to the back-end for conversion to Verilog. By convention, classes that generate logic implement a method called "get_fragment". When called, this method builds a new fragment implementing the desired functionality of the class, and returns it. This convention allows fragments to be built automatically by combining the fragments from all relevant objects in the local scope, by using the autofragment module. Migen Core Logic ================ Migen Core Logic is a convenience library of common logic circuits implemented using FHDL: - a multi-cycle integer divider. - a round-robin arbiter, useful to build bus arbiters. - a multiplexer bank (multimux), useful to multiplex composite (grouped) signals. - a condition-triggered static scheduler of FHDL synchronous statements (timeline). Migen Bus ========= Migen Bus contains classes providing a common structure for master and slave interfaces of the following buses: - Wishbone [5], the general purpose bus recommended by Opencores. - CSR-NG, a low-bandwidth, resource-sensitive bus designed for accessing the configuration and status registers of cores from software. - FastMemoryLink-NG, a split-transaction bus optimized for use with a high-performance, out-of-order SDRAM controller. (TODO) It also provides interconnect components for these buses, such as arbiters and address decoders. The strength of the Migen procedurally generated logic can be illustrated by the following example: wbcon = wishbone.InterconnectShared( [cpu.ibus, cpu.dbus, ethernet.dma, audio.dma], [(0, norflash.bus), (1, wishbone2fml.wishbone), (3, wishbone2csr.wishbone)]) In this example, the interconnect component generates a 4-way round-robin arbiter, multiplexes the master bus signals into a shared bus, determines that the address decoding must occur on 2 bits, and connects all slave interfaces to the shared bus, inserting the address decoder logic in the bus cycle qualification signals and multiplexing the data return path. It can recognize the signals in each core's bus interface thanks to the common structure mandated by Migen Bus. All this happens automatically, using only that much user code. The resulting interconnect logic can be retrieved using wbcon.get_fragment(), and combined with the fragments from the rest of the system. Migen Bank ========== Migen Bank is a system comparable to wishbone-gen [6], which automates the creation of configuration and status register banks and (TODO) interrupt/event managers implemented in cores. Bank takes a description made up of a list of registers and generates logic implementing it with a slave interface compatible with Migen Bus. A register can be "raw", which means that the core has direct access to it. It also means that the register width must be less or equal to the bus word width. In that case, the register object provides the following signals: - dev_r, which contains the data written from the bus interface. - dev_re, which is the strobe signal for dev_r. It is active for one cycle, after or during a write from the bus. dev_r is only valid when dev_re is high. - dev_w, which must provide at all times the value to be read from the bus. Registers that are not raw are managed by Bank and contain fields. If the sum of the widths of all fields attached to a register exceeds the bus word width, the register will automatically be sliced into words of the maximum size and implemented at consecutive bus addresses, MSB first. Field objects have two parameters, access_bus and access_dev, determining respectively the access policies for the bus and core sides. They can take the values READ_ONLY, WRITE_ONLY and READ_WRITE. If the device can read, the field object provides the dev_r signal, which contains at all times the current value of the field (kept by the logic generated by Bank). If the device can write, the field object provides the following signals: - dev_w, which provides the value to be written into the field. - dev_we, which strobes the value into the field. Migen Flow (TODO) ========== Many hardware acceleration problems can be expressed in the dataflow paradigm, that is, using a directed graph representing the flow of data between actors. Actors in Migen are written directly in FHDL. This maximizes the flexibility: for example, an actor can implement a DMA master to read data from system memory. It is conceivable that a CAL [7] to FHDL compiler be implemented at some point, to support higher level descriptions of some actors and reuse of third-party RVC-CAL applications. [8] [9] [10] Actors communicate by exchanging tokens, whose flow is typically controlled using handshake signals (strobe/ack). Each actor has a "scheduling model". It can be: - N-sequential: the actor fires when tokens are available at all its inputs, and it produces one output token after N cycles. It cannot accept new input tokens until it has produced its output. A multicycle integer divider would use this model. - N-pipelined: similar to the sequential model, but the actor can always accept new input tokens. It produces an output token N cycles of latency after accepting input tokens. A pipelined multiplier would use this model. - Dynamic: the general case, when no simple hypothesis can be made on the token flow behaviour of the actor. An actor accessing system memory on a shared bus would use this model. Migen Flow automatically generates handshake logic for the first two scheduling models. In the third case, the FHDL descriptions for the logic driving the handshake signals must be provided by the actor. If sequential or pipelined actors are connected together, Migen Flow will attempt to find a static schedule, remove the handshake signals, optimize away the control logic in each actor and replace it with a centralized FSM implementing the static schedule. An actor can be a composition of other actors. Actor graphs are managed using the NetworkX [11] library. References: [ 1] http://milkymist.org [ 2] http://www.myhdl.org [ 3] http://milkymist.org/thesis/thesis.pdf [ 4] http://www.xilinx.com/publications/archives/xcell/Xcell77.pdf p30-35 [ 5] http://cdn.opencores.org/downloads/wbspec_b4.pdf [ 6] http://www.ohwr.org/projects/wishbone-gen [ 7] http://opendf.svn.sourceforge.net/viewvc/opendf/trunk/doc/ GentleIntro/GentleIntro.pdf [ 8] http://orcc.sourceforge.net/ [ 9] http://orc-apps.sourceforge.net/ [10] http://opendf.sourceforge.net/ [11] http://networkx.lanl.gov/ Practical information ===================== Code repository: https://github.com/milkymist/migen Experimental version of the Milkymist SoC based on Migen: https://github.com/milkymist/milkymist-ng Migen is designed for Python 3.2. Send questions, comments and patches to devel [AT] lists.milkymist.org We are also on IRC: #milkymist on the Freenode network. Migen is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Unless otherwise noted, Migen's source code is copyright (C) 2011 Sebastien Bourdeauducq. Authors retain ownership of their contributions. |
From: Tom F. <fit...@gm...> - 2011-12-16 00:03:00
|
On 12/15/2011 2:23 PM, Norbo wrote: > Am 15.12.2011, 03:24 Uhr, schrieb Tom Fitz<fit...@gm...>: > >> Hello, >> I know this topic has been discussed before, but I still do not >> understand it. I am trying to make a bidirectional bus for an external >> sram. I can't figure out how to use TristateSignal. >> >> I have di (data in) , do (data out) , ld (latch data) , and read. When >> read is on I want latch_data to be read to data_in and when it is >> off I want di to be written to the latch_data. Here is what I have: >> >> from myhdl import * >> from random import randrange >> >> def Buffer(do, di, ld, read): >> >> buff = TristateSignal(intbv(0)[16:]) >> driver1 = buff.driver() >> driver2 = buff.driver() >> >> @always_comb >> def logic(): >> if read == 0: >> driver1.next = do.val >> ld.next = driver1.val >> driver2.next = None >> else: >> driver1.next = None >> driver2.next = ld.val >> di.next = driver2.val >> >> return logic >> >> ld = TristateSignal(intbv(0)[16:]) >> do, di = [Signal(intbv(0)[16:]) for i in range(2)] >> clock, read = [Signal(bool(0)) for i in range(2)] >> >> tristate_buf_inst = Buffer(do, di, ld, read) >> >> def test_tristate(): >> >> @always(delay(10)) >> def clkgen(): >> clock.next = not clock >> >> @instance >> def stimulus(): >> ram = [ ] # holds random values generated during writing stage >> >> print "Writing" >> print "now", "do", "di", "ld" >> >> for i in range(5): >> data = randrange(255) >> do.next = data >> ram.append(data) >> yield clock.negedge >> >> print "Reading" >> print "now", "q_do", "di", "ld" >> for i in range(5): >> read.next = 1 >> ld.next = ram[i] >> yield delay(10) >> >> raise StopSimulation >> >> @always(clock.negedge) >> def monitor(): >> print now(), do, di, ld >> >> return tristate_buf_inst, clkgen, stimulus, monitor >> >> sim = Simulation(test_tristate()) >> sim.run() >> >> This raises an error that ld is being used as an inout signal. I've done >> variations on this and was able to >> pipe data from do to ld, but not from ld to di by making ld a tristate. >> How do I configure the bridge (tristate) >> to deliver data correctly when I can only set one end? Should ld be the >> tristate since it is the only inout >> signal? If so, how do I set ld in my test in order to pipe data from ld >> to di? >> >> Any help is welcome. Thank you for your time and consideration. > > > Is it something like this you wanted to do? i wasnt so sure because in the > text > you were talking about di but in the code there was a do?? > > > > from myhdl import * > from random import randrange > > def Buffer(do, di, ld, read): > > buff = TristateSignal(intbv(0)[16:]) > driver1 = buff.driver() > driver2 = buff.driver() > > @always_comb > def logic(): > if read == 0: > ld.next = do.val > > @always_comb > def logic2(): > if read == 1: > di.next = ld.val > > return logic,logic2 > > ld = Signal(intbv(0)[16:]) > do, di = [Signal(intbv(0)[16:]) for i in range(2)] > clock, read = [Signal(bool(0)) for i in range(2)] > > tristate_buf_inst = Buffer(do, di, ld, read) > > def test_tristate(): > > @always(delay(10)) > def clkgen(): > clock.next = not clock > > @instance > def stimulus(): > ram = [ ] # holds random values generated during writing stage > > print "Writing" > print "now", "do", "di", "ld" > > for i in range(5): > data = randrange(255) > do.next = data > ram.append(data) > yield clock.negedge > > yield clock.posedge > print "Reading" > print "now", "q_do", "di", "ld" > for i in range(5): > read.next = 1 > ld.next = ram[i] > yield clock.negedge #yield delay(10) > > raise StopSimulation > > @always(clock.negedge) > def monitor(): > print now(), do, di, ld > > return tristate_buf_inst, clkgen, stimulus, monitor > > sim = Simulation(test_tristate()) > sim.run() > > > ------------------------------------------------------------------------------ > 10 Tips for Better Server Consolidation > Server virtualization is being driven by many needs. > But none more important than the need to reduce IT complexity > while improving strategic productivity. Learn More! > http://www.accelacomm.com/jaw/sdnl/114/51507609/ > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list Wow. Thank you so much. I swear I had tried that, but maybe I wrote my test the wrong way. That's amazing. I was really barking up the wrong tree with the tristates. I think the essential thing I missed was using always_comb's in my initial attempts. |
From: Norbo <Nor...@gm...> - 2011-12-15 22:23:57
|
Am 15.12.2011, 03:24 Uhr, schrieb Tom Fitz <fit...@gm...>: > > Hello, > I know this topic has been discussed before, but I still do not > understand it. I am trying to make a bidirectional bus for an external > sram. I can't figure out how to use TristateSignal. > > I have di (data in) , do (data out) , ld (latch data) , and read. When > read is on I want latch_data to be read to data_in and when it is > off I want di to be written to the latch_data. Here is what I have: > > from myhdl import * > from random import randrange > > def Buffer(do, di, ld, read): > > buff = TristateSignal(intbv(0)[16:]) > driver1 = buff.driver() > driver2 = buff.driver() > > @always_comb > def logic(): > if read == 0: > driver1.next = do.val > ld.next = driver1.val > driver2.next = None > else: > driver1.next = None > driver2.next = ld.val > di.next = driver2.val > > return logic > > ld = TristateSignal(intbv(0)[16:]) > do, di = [Signal(intbv(0)[16:]) for i in range(2)] > clock, read = [Signal(bool(0)) for i in range(2)] > > tristate_buf_inst = Buffer(do, di, ld, read) > > def test_tristate(): > > @always(delay(10)) > def clkgen(): > clock.next = not clock > > @instance > def stimulus(): > ram = [ ] # holds random values generated during writing stage > > print "Writing" > print "now", "do", "di", "ld" > > for i in range(5): > data = randrange(255) > do.next = data > ram.append(data) > yield clock.negedge > > print "Reading" > print "now", "q_do", "di", "ld" > for i in range(5): > read.next = 1 > ld.next = ram[i] > yield delay(10) > > raise StopSimulation > > @always(clock.negedge) > def monitor(): > print now(), do, di, ld > > return tristate_buf_inst, clkgen, stimulus, monitor > > sim = Simulation(test_tristate()) > sim.run() > > This raises an error that ld is being used as an inout signal. I've done > variations on this and was able to > pipe data from do to ld, but not from ld to di by making ld a tristate. > How do I configure the bridge (tristate) > to deliver data correctly when I can only set one end? Should ld be the > tristate since it is the only inout > signal? If so, how do I set ld in my test in order to pipe data from ld > to di? > > Any help is welcome. Thank you for your time and consideration. Is it something like this you wanted to do? i wasnt so sure because in the text you were talking about di but in the code there was a do?? from myhdl import * from random import randrange def Buffer(do, di, ld, read): buff = TristateSignal(intbv(0)[16:]) driver1 = buff.driver() driver2 = buff.driver() @always_comb def logic(): if read == 0: ld.next = do.val @always_comb def logic2(): if read == 1: di.next = ld.val return logic,logic2 ld = Signal(intbv(0)[16:]) do, di = [Signal(intbv(0)[16:]) for i in range(2)] clock, read = [Signal(bool(0)) for i in range(2)] tristate_buf_inst = Buffer(do, di, ld, read) def test_tristate(): @always(delay(10)) def clkgen(): clock.next = not clock @instance def stimulus(): ram = [ ] # holds random values generated during writing stage print "Writing" print "now", "do", "di", "ld" for i in range(5): data = randrange(255) do.next = data ram.append(data) yield clock.negedge yield clock.posedge print "Reading" print "now", "q_do", "di", "ld" for i in range(5): read.next = 1 ld.next = ram[i] yield clock.negedge #yield delay(10) raise StopSimulation @always(clock.negedge) def monitor(): print now(), do, di, ld return tristate_buf_inst, clkgen, stimulus, monitor sim = Simulation(test_tristate()) sim.run() |
From: Tom F. <fit...@gm...> - 2011-12-15 21:28:52
|
On 12/15/2011 4:35 AM, Christopher Felton wrote: > On 12/14/2011 8:24 PM, Tom Fitz wrote: >> Hello, >> I know this topic has been discussed before, but I still do not >> understand it. I am trying to make a bidirectional bus for an external >> sram. I can't figure out how to use TristateSignal. >> > If you have not reviewed this MEP, > http://www.myhdl.org/doku.php/meps:mep-105, it is worthwhile reviewing > to get more background on the latest TriState (ShadowSignal) implementation. > > I will gladly look over your posted code but it will be a couple days > (maybe even a week) before I can get to it. > > Regards, > Chris > > > ------------------------------------------------------------------------------ > 10 Tips for Better Server Consolidation > Server virtualization is being driven by many needs. > But none more important than the need to reduce IT complexity > while improving strategic productivity. Learn More! > http://www.accelacomm.com/jaw/sdnl/114/51507609/ > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list Thank you. Anything helps, even a better explanation of the concepts. I had already read that page, but it did give so new insights this time around. I understand how to use vanilla shadow signals, but I can't figure out tristates. I'll keep working at it and post my progress. Thanks again. |
From: Christopher F. <chr...@gm...> - 2011-12-15 12:36:05
|
On 12/14/2011 8:24 PM, Tom Fitz wrote: > > Hello, > I know this topic has been discussed before, but I still do not > understand it. I am trying to make a bidirectional bus for an external > sram. I can't figure out how to use TristateSignal. > If you have not reviewed this MEP, http://www.myhdl.org/doku.php/meps:mep-105, it is worthwhile reviewing to get more background on the latest TriState (ShadowSignal) implementation. I will gladly look over your posted code but it will be a couple days (maybe even a week) before I can get to it. Regards, Chris |
From: Tom F. <fit...@gm...> - 2011-12-15 02:24:34
|
Hello, I know this topic has been discussed before, but I still do not understand it. I am trying to make a bidirectional bus for an external sram. I can't figure out how to use TristateSignal. I have di (data in) , do (data out) , ld (latch data) , and read. When read is on I want latch_data to be read to data_in and when it is off I want di to be written to the latch_data. Here is what I have: from myhdl import * from random import randrange def Buffer(do, di, ld, read): buff = TristateSignal(intbv(0)[16:]) driver1 = buff.driver() driver2 = buff.driver() @always_comb def logic(): if read == 0: driver1.next = do.val ld.next = driver1.val driver2.next = None else: driver1.next = None driver2.next = ld.val di.next = driver2.val return logic ld = TristateSignal(intbv(0)[16:]) do, di = [Signal(intbv(0)[16:]) for i in range(2)] clock, read = [Signal(bool(0)) for i in range(2)] tristate_buf_inst = Buffer(do, di, ld, read) def test_tristate(): @always(delay(10)) def clkgen(): clock.next = not clock @instance def stimulus(): ram = [ ] # holds random values generated during writing stage print "Writing" print "now", "do", "di", "ld" for i in range(5): data = randrange(255) do.next = data ram.append(data) yield clock.negedge print "Reading" print "now", "q_do", "di", "ld" for i in range(5): read.next = 1 ld.next = ram[i] yield delay(10) raise StopSimulation @always(clock.negedge) def monitor(): print now(), do, di, ld return tristate_buf_inst, clkgen, stimulus, monitor sim = Simulation(test_tristate()) sim.run() This raises an error that ld is being used as an inout signal. I've done variations on this and was able to pipe data from do to ld, but not from ld to di by making ld a tristate. How do I configure the bridge (tristate) to deliver data correctly when I can only set one end? Should ld be the tristate since it is the only inout signal? If so, how do I set ld in my test in order to pipe data from ld to di? Any help is welcome. Thank you for your time and consideration. |
From: Norbo <Nor...@gm...> - 2011-12-14 19:10:00
|
Am 13.12.2011, 14:25 Uhr, schrieb Christopher Felton <chr...@gm...>: > On 12/12/11 1:40 PM, Norbo wrote: >> hello >> > > <snip> > > If you change the code, slightly it will convert without error. I did > not look at the generated VHDL (don't have a VHDL sim/syn on this > computer). The example you submitted, doesn't make too much sense > because the "select" signal is internal to you TOP module. Essentially > the circuit being described would have no inputs, hence the > "_error.EmptySensitivityList" error. > > Hope this helps, > Chris > > ~~~~~[ Modified code ]~~~~ > from myhdl import * > from random import randrange > > ENUM_TYPE = enum('GIVE_ONE', 'GIVE_TWO') > > def TOP(outvalue, sel_value): > > @always_comb > def combi_sel(): > if sel_value == ENUM_TYPE.GIVE_ONE : > outvalue.next=1 > elif sel_value == ENUM_TYPE.GIVE_TWO : > outvalue.next=2 > > return instances() > > > def test_bench(): > outsignal=Signal(intbv(0)[4:]) > sel_value=Signal(ENUM_TYPE.GIVE_TWO) > instanc_top=TOP(outsignal, sel_value) > > interval = delay(10) > @instance > def stimulus(): > sel_value.next = ENUM_TYPE.GIVE_TWO > yield delay(1) > print "Value of Output is", outsignal > sel_value.next = ENUM_TYPE.GIVE_ONE > yield delay(1) > print "Value of Output is", outsignal > > raise StopSimulation > > return stimulus,instanc_top > > > if __name__ == '__main__': > hello_inst = test_bench() > > sim = Simulation(hello_inst) > print "-"*30 + "Simulation Started" + "-"*30 > sim.run(10) > print "-"*30 + "Simulation Finished" + "-"*30 > > > outsignal=Signal(intbv(0)[4:]) > sel_value=Signal(ENUM_TYPE.GIVE_TWO) > > print "-"*30 + "Conversion To VHDL Started" + "-"*30 > toVHDL(TOP,outsignal, sel_value) the Thing is that if a bool or a intbv is used the code in exactly the same manner, it works. For me the ability to put a konstant signal inside the module seems to be quite usefull in some cases. In the following there are some cases which might show some inconsistencies. The case that the bool is comparable with a intbv of 1 bit length would may just be a nice to have. ;) ------------------------------------ def TOP(outvalue): sel_value=Signal(bool(0)) @always_comb def combi_sel(): if sel_value == bool(0) : outvalue.next=1 elif sel_value == bool(1) : outvalue.next=2 return instances() Simulation Works, Conversion to VHDL Works, and Synthesis of VHDL Works ------------------------------------ ------------------------------------ def TOP(outvalue): sel_value=Signal(bool(0)) @always_comb def combi_sel(): if sel_value == 0 : outvalue.next=1 elif sel_value == 1 : outvalue.next=2 return instances() Simulation Works, Conversion to VHDL Fails!! (TypeError: Unexpected type) Conversion to Verilog same Error ------------------------------------ ------------------------------------ def TOP(outvalue): sel_value=Signal(bool(0)) @always_comb def combi_sel(): if sel_value == 0 : outvalue.next=1 elif sel_value == bool(1) : outvalue.next=2 return instances() Simulation Works, Conversion to VHDL Works, and Synthesis of VHDL Works!! ------------------------------------ ------------------------------------ def TOP(outvalue): sel_value=Signal(intbv(0)[1:]) @always_comb def combi_sel(): if sel_value == 0 : outvalue.next=1 elif sel_value == 1 : outvalue.next=2 return instances() Simulation Works, Conversion to VHDL Works, Synthesis VHDL Works!! ------------------------------------ ------------------------------------ def TOP(outvalue): sel_value=Signal(intbv(0)[1:]) @always_comb def combi_sel(): if sel_value == bool(0) : outvalue.next=1 elif sel_value == bool(1) : outvalue.next=2 return instances() Simulation Works, Conversion to VHDL Works, Synthesis of VHDL Fails (No matching overload for "=") !! Synthesis of Veriolog Works !! ------------------------------------ ------------------------------------ def TOP(outvalue): sel_value=Signal(intbv(0)[1:]) @always_comb def combi_sel(): if sel_value == 0 : outvalue.next=1 elif sel_value == bool(1) : outvalue.next=2 return instances() Simulation Works, Conversion to VHDL Works, Synthesis of VHDL Fails (No matching overload for "=") !! ------------------------------------ ------------------------------------ ENUM_TYPE = enum('GIVE_ONE', 'GIVE_TWO') def TOP(outvalue): sel_value=Signal(ENUM_TYPE.GIVE_ONE) @always_comb def combi_sel(): if sel_value == ENUM_TYPE.GIVE_ONE: outvalue.next=1 elif sel_value == ENUM_TYPE.GIVE_TWO : outvalue.next=2 return instances() Simulation Works, Conversion to VHDL Fails with error: Traceback (most recent call last): File "Case2.py", line 45, in <module> toVHDL(TOP,outsignal) File "/usr/local/lib/python2.7/dist-packages/myhdl/conversion/_toVHDL.py", line 165, in __call__ _convertGens(genlist, siglist, vfile) File "/usr/local/lib/python2.7/dist-packages/myhdl/conversion/_toVHDL.py", line 392, in _convertGens assert 0 AssertionError Conversion to Veriolog Fails with: Traceback (most recent call last): File "Case2.py", line 45, in <module> toVerilog(TOP,outsignal) File "/usr/local/lib/python2.7/dist-packages/myhdl/conversion/_toVerilog.py", line 149, in __call__ _writeSigDecls(vfile, intf, siglist, memlist) File "/usr/local/lib/python2.7/dist-packages/myhdl/conversion/_toVerilog.py", line 291, in _writeSigDecls print >> f, "assign %s = %s;" % (s._name, int(s._val)) TypeError: int() argument must be a string or a number, not 'EnumItem' ------------------------------------ |
From: Norbo <Nor...@gm...> - 2011-12-13 16:59:35
|
This is just a post to show off with my continuous wave sinus generator. It uses the recursive chebyshev formulation to compute the values of a Sin waveform. To compute the value it uses only one multiplication with a constant(if the sin waveform frequency is constant) and a substraction, so it has relative low resource usage. Normaly generating a continuous sin waveform in Hardware/VHDL is done with Direct Digital Synthesis using a phase accumulater and stored values with interpolation between values and stuff like that, but i think my design has in some cases advantages over this approach. I wanted to do it a long time ago, but with simulation and verifying the sinus spectrally it would have been quit a lot of work with VHDL, thanks to myhdl, makeing this like this is kind of fun. (i used pylab for the printing with the matplotlib) Now the Code in (license: have fun with the code to do whatever you like, or if you can ask Pafnuty Chebyshev for permission to use): from myhdl import * from math import cos,pi import pylab def unit_singen(i_clk,i_reset,i_enable,o_outvalue,frequenzSIN,clkfrequnez): INTERNALWIDTH=len(o_outvalue)-2 # #OUT_MAX_POSSIBLE=o_outvalue.max #OUT_MIN_POSSIBLE=o_outvalue.min KONSTANT_FACTOR=int(cos(2*pi*frequenzSIN*1.0/clkfrequnez)*2**(INTERNALWIDTH)) Reg_T0=Signal(intbv((2**(INTERNALWIDTH))-1,min=o_outvalue.min,max=o_outvalue.max)) Reg_T1=Signal(intbv(KONSTANT_FACTOR,min=o_outvalue.min,max=o_outvalue.max)) @always(i_clk.posedge,i_reset.negedge) def logicCC(): if i_reset== 0 : Reg_T0.next=(2**(INTERNALWIDTH))-1 Reg_T1.next=KONSTANT_FACTOR else: if i_enable==1: Reg_T0.next=Reg_T1 Reg_T1.next=((KONSTANT_FACTOR * Reg_T1)>>(INTERNALWIDTH-1)) - Reg_T0 @always_comb def comb_logic(): #if Reg_T1>=OUT_MAX_POSSIBLE: #o_outvalue.next=OUT_MAX_POSSIBLE-1 #elif Reg_T1<=OUT_MIN_POSSIBLE: #o_outvalue.next=OUT_MIN_POSSIBLE #else: o_outvalue.next=Reg_T1 return instances() def test_singen(SimulateNPoints=200): Sinusvalue=Signal(intbv(0,min=-2**30,max=2**30)) clk=Signal(bool(0)) enable=Signal(bool(0)) reset=Signal(bool(0)) frequenzSIN=1e6 # make a 10 mhz Sinus clk_frequnez=100e6 # 100 mhz clk_period=1.0/clk_frequnez singen_inst = unit_singen(clk,reset,enable,Sinusvalue,frequenzSIN,clk_frequnez) @always(delay(int(clk_period*0.5*1e9))) ## delay in nano sekonds def clkgen(): clk.next = not clk sinlist=[] @instance def stimulus(): while 1: reset.next=0 enable.next=0 yield clk.posedge reset.next=1 yield clk.posedge enable.next=1 for i in range(SimulateNPoints): yield clk.posedge #yield delay(10) sinlist.append(int(Sinusvalue)) print Sinusvalue pylab.figure(1) pylab.subplot(211) pylab.plot(pylab.arange(0.0,clk_period*(len(sinlist)),clk_period),sinlist) pylab.subplot(212) pylab.semilogy(pylab.arange(-clk_frequnez/2.0,clk_frequnez/2.0,clk_frequnez/(len(sinlist))),abs(pylab.fftshift(pylab.fft(pylab.array(sinlist))))) pylab.show() raise StopSimulation toVHDL(unit_singen,clk,reset,enable,Sinusvalue,frequenzSIN,clk_frequnez) return instances() # if __name__ == '__main__': sim = Simulation(test_singen()) sim.run() #singen_inst = unit_singen(Outvalue,clk,enable,reset,frequenz=20) #toVHDL(unit_singen,clk,reset,enable,Outvalue,frequenz) #simulate(2000) |
From: Christopher F. <chr...@gm...> - 2011-12-13 13:25:44
|
On 12/12/11 1:40 PM, Norbo wrote: > hello > > <snip> If you change the code, slightly it will convert without error. I did not look at the generated VHDL (don't have a VHDL sim/syn on this computer). The example you submitted, doesn't make too much sense because the "select" signal is internal to you TOP module. Essentially the circuit being described would have no inputs, hence the "_error.EmptySensitivityList" error. Hope this helps, Chris ~~~~~[ Modified code ]~~~~ from myhdl import * from random import randrange ENUM_TYPE = enum('GIVE_ONE', 'GIVE_TWO') def TOP(outvalue, sel_value): @always_comb def combi_sel(): if sel_value == ENUM_TYPE.GIVE_ONE : outvalue.next=1 elif sel_value == ENUM_TYPE.GIVE_TWO : outvalue.next=2 return instances() def test_bench(): outsignal=Signal(intbv(0)[4:]) sel_value=Signal(ENUM_TYPE.GIVE_TWO) instanc_top=TOP(outsignal, sel_value) interval = delay(10) @instance def stimulus(): sel_value.next = ENUM_TYPE.GIVE_TWO yield delay(1) print "Value of Output is", outsignal sel_value.next = ENUM_TYPE.GIVE_ONE yield delay(1) print "Value of Output is", outsignal raise StopSimulation return stimulus,instanc_top if __name__ == '__main__': hello_inst = test_bench() sim = Simulation(hello_inst) print "-"*30 + "Simulation Started" + "-"*30 sim.run(10) print "-"*30 + "Simulation Finished" + "-"*30 outsignal=Signal(intbv(0)[4:]) sel_value=Signal(ENUM_TYPE.GIVE_TWO) print "-"*30 + "Conversion To VHDL Started" + "-"*30 toVHDL(TOP,outsignal, sel_value) |
From: Norbo <Nor...@gm...> - 2011-12-12 19:54:52
|
ok sorry forget about case 1 which is driving a constant and has been already discussed. greetings Norbert |
From: Norbo <Nor...@gm...> - 2011-12-12 19:40:39
|
hello lets say e.g i have written code like: ########################Case 1: (code)##################### from myhdl import * from random import randrange def TOP(outvalue): sigTest=Signal(intbv(0)[4:]) @always_comb def comb_setConst(): sigTest.next=4 @always_comb def combi_sel(): if sigTest == 1: outvalue.next=1 elif sigTest == 4: outvalue.next=2 return instances() def test_bench(): outsignal=Signal(intbv(0)[4:]) instanc_top=TOP(outsignal) interval = delay(10) @always(interval) def stimulus(): print "Value of Output is", outsignal return stimulus,instanc_top if __name__ == '__main__': hello_inst = test_bench() sim = Simulation(hello_inst) sim.run(10) outsignal=Signal(intbv(0)[4:]) toVHDL(TOP,outsignal) ############################################################# ####################Console Output:################################# Traceback (most recent call last): File "notDriven.py", line 39, in <module> hello_inst = test_bench() File "notDriven.py", line 28, in test_bench instanc_top=TOP(outsignal) File "notDriven.py", line 12, in TOP @always_comb File "/usr/local/lib/python2.7/dist-packages/myhdl/_always_comb.py", line 64, in always_comb c = _AlwaysComb(func, symdict) File "/usr/local/lib/python2.7/dist-packages/myhdl/_always_comb.py", line 203, in __init__ raise AlwaysCombError(_error.EmptySensitivityList) myhdl.AlwaysCombError: sensitivity list is empty ########################################################### its because of this lines in the code --------------------------- sigTest=Signal(intbv(0)[4:]) @always_comb def comb_setConst(): sigTest.next=4 --------------------------- which in my understanding should be valid code #################Case 2: (code)################################# from myhdl import * from random import randrange ENUM_TYPE = enum('GIVE_ONE', 'GIVE_TWO') def TOP(outvalue): sel_value=Signal(ENUM_TYPE.GIVE_TWO) #sel_value=Signal(intbv(0)[4:]) @always_comb def combi_sel(): if sel_value == ENUM_TYPE.GIVE_ONE : outvalue.next=1 elif sel_value == ENUM_TYPE.GIVE_TWO : outvalue.next=2 return instances() def test_bench(): outsignal=Signal(intbv(0)[4:]) instanc_top=TOP(outsignal) interval = delay(10) @always(interval) def stimulus(): print "Value of Output is", outsignal return stimulus,instanc_top if __name__ == '__main__': hello_inst = test_bench() sim = Simulation(hello_inst) print "-"*30 + "Simulation Started" + "-"*30 sim.run(10) print "-"*30 + "Simulation Finished" + "-"*30 outsignal=Signal(intbv(0)[4:]) print "-"*30 + "Conversion To VHDL Started" + "-"*30 toVHDL(TOP,outsignal) ############################################################# #############Console Output:############################### ------------------------------Simulation Started------------------------------ Value of Output is 2 <class 'myhdl._SuspendSimulation'>: Simulated 10 timesteps ------------------------------Simulation Finished------------------------------ ------------------------------Conversion To VHDL Started------------------------------ ** ToVHDLWarning: Signal is not driven: sel_value Traceback (most recent call last): File "Case2.py", line 45, in <module> toVHDL(TOP,outsignal) File "/usr/local/lib/python2.7/dist-packages/myhdl/conversion/_toVHDL.py", line 165, in __call__ _convertGens(genlist, siglist, vfile) File "/usr/local/lib/python2.7/dist-packages/myhdl/conversion/_toVHDL.py", line 392, in _convertGens assert 0 AssertionError #################################################### The Simulation runs but the conversion too vhdl or to Verilog aborts if i dont use a ENUM Signal for the "sel_value" the conversion works so the unit changes to: #############Case 2.5 (code)################# def TOP(outvalue): #sel_value=Signal(ENUM_TYPE.GIVE_TWO) sel_value=Signal(intbv(0)[4:]) @always_comb def combi_sel(): if sel_value == ENUM_TYPE.GIVE_ONE : outvalue.next=1 elif sel_value == ENUM_TYPE.GIVE_TWO : outvalue.next=2 return instances() ###################################### then the simulation runs and the conversion works the only warning is ** ToVHDLWarning: Signal is not driven: sel_value the resulting .vhd is not synthesisable because there is no "=" operator for enum type and unsingned |
From: Christopher F. <chr...@gm...> - 2011-12-08 12:19:46
|
On 12/6/11 8:12 AM, Norbo wrote: > On Sat, 03 Dec 2011 19:39:26 +0100, Christopher Felton > <chr...@gm...> wrote: > >> On 11/30/11 9:52 AM, Norbo wrote: >>> On Wed, 30 Nov 2011 13:39:25 +0100, Christopher Felton >>> <chr...@gm...> wrote: >>> >>>> On 11/30/11 5:48 AM, Norbo wrote: >>>>> On Wed, 23 Nov 2011 17:13:27 +0100, Christopher Felton >>>>> <chr...@gm...> wrote: >>>>> >>>>>> On 11/22/11 3:15 PM, Norbo wrote: >>>>>>> On Mon, 21 Nov 2011 17:28:05 +0100, Christopher Felton >>>>>>> <chr...@gm...> wrote: >>>>>>> >>>>>>>> On 11/21/2011 8:52 AM, Oscar Diaz wrote: >>>>>>>>> 2011/11/19 Norbo<Nor...@gm...>: >>>>>>>>>> I have played a bit with myhdl and created the following: >>>>>>>>>> >>>>>>>>>> ---------------------------------------------------------- >>>>>>>>>> from myhdl import * >>>>>>>>>> >>>>>>>>>> def bin2gray(A,B, C, width): >>>>>>>>>> >>>>>>>>>> """ Gray encoder. >>>>>>>>>> >>>>>>>>>> B -- input intbv signal, binary encoded >>>>>>>>>> G -- output intbv signal, gray encoded >>>>>>>>>> width -- bit width >>>>>>>>>> >>>>>>>>>> """ >>>>>>>>>> @always_comb >>>>>>>>>> def logic(): >>>>>>>>>> C[0].next = A + B >>>>>>>>> >>>>>>>>> It seems that you have a bug here. Why you assign the result of a >>>>>>>>> sum >>>>>>>>> to a single bit? that's the reason why the converter tried to use >>>>>>>>> "to_std_logic" for the output. If you want a normal sum, it should >>>>>>>>> be >>>>>>>>> >>>>>>>>> C.next = A + B >>>>>>>>> >>>>>>>>> and the VHDL converter will put synthesizable code: >>>>>>>>> >>>>>>>>> C<= (A + B); >>>>>>>>> >>>>>>>> >>>>>>>> Good eye Oscar! >>>>>>>> >>>>>>>> Yes, there are a couple issues with the bin2gray that was provided >>>>>>>> (I >>>>>>>> assumed the bin2gray was an example for conversion means and not an >>>>>>>> actual bin2gray?). I didn't notice at first glance but if you want >>>>>>>> to >>>>>>>> assign a single bit of a bit-vector you need to do: >>>>>>>> >>>>>>>> C.next[0] = A + B >>>>>>>> >>>>>>>> >>>>>>>> If you assign the bit correctly the conversion works (even though >>>>>>>> it >>>>>>>> functional doesn't work). Simulation will not work!. Not sure why >>>>>>>> the >>>>>>>> converter didn't flag this? Possible error detection enhancement. >>>>>>>> >>>>>>>> Also using the "+" operator instead of the bitwise "^" will cause >>>>>>>> problems in simulation. The "+" will overflow the range for a >>>>>>>> single >>>>>>>> bit. >>>>>>>> >>>>>>>> My previous reply can be ignored and should be ignored. If any >>>>>>>> changes >>>>>>>> need to be made they would be in the error catching/reporting and >>>>>>>> not >>>>>>>> modifications to the conversion. >>>>>>>> >>>>>>>> Regards, >>>>>>>> Chris >>>>>>>> >>>>>>>>> Or, if you want a binary to gray encoder, just use the example >>>>>>>>> from >>>>>>>>> the documentation >>>>>>>>> >>>>>>>>> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >>>>>>>>> >>>>>>>>> >>>>>>>>> Best Regards >>>>>>>>> >>>>>>> >>>>>>> Well the thing is: >>>>>>> >>>>>>> If i write: >>>>>>> >>>>>>> C[4:0].next = A+B in vhdl it gets -> C(4-1 downto 0)<= >>>>>>> resize(A >>>>>>> + >>>>>>> B,4); >>>>>>> >>>>>>> or: >>>>>>> >>>>>>> C[1:0].next = A+B in vhdl it gets -> C(1-1 downto 0)<= >>>>>>> resize(A + >>>>>>> B,1); >>>>>>> which in in my understanding this makes kind of sense because the >>>>>>> result >>>>>>> is cropped to the output size. (maybe a warning would be nice, but >>>>>>> it >>>>>>> could be difficult if the calculation gets longer) >>>>>>> >>>>>>> >>>>>>> but when i write : >>>>>>> >>>>>>> C[0].next = A+B >>>>>>> (which is actually the same as the above C[1:0].next = A+B) >>>>>>> in vhdl it gets -> C(0)<= to_std_logic(A + B); >>>>>>> and is not synthesisable. >>>>>>> >>>>>>> >>>>>> >>>>>> As mentioned, the above is the incorrect syntax. The converted >>>>>> results >>>>>> are unreliable. To do bit indexing you need to do: >>>>>> >>>>>> C.next[0] = A[0] + B[1] >>>>>> >>>>>> If you do C[0].next that is used for a list of signals. If you run a >>>>>> simulation (testbench) this error will be identified. >>>>>> >>>>>> Review the following links: >>>>>> http://www.myhdl.org/doc/current/manual/intro.html#bit-indexing >>>>>> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >>>>>> >>>>>> Also, run a simple simulation. That will give you some more insight >>>>>> into the issue. >>>>>> >>>>>> Regards, >>>>>> Chris >>>>> >>>>> Sorry that i keep bagging, i really like myhdl and i really want to >>>>> get >>>>> it >>>>> better >>>>> so if i write: >>>>> >>>>> C.next[0] = A[0] + B[1] >>>>> >>>>> the line which is produced is: >>>>> >>>>> C(0)<= to_std_logic(to_unsigned(A(0), 1) + to_unsigned(B(0), 1)); >>>>> >>>>> and it is not synthesisable because of the to_std_logic. >>>> >>>> Correct, the conversion generated an equivilant assignment. Which is >>>> not synthesizable (it is syntactically correct and will compile with a >>>> VHDL simulator). But the two statements are equivalent. If you run a >>>> MyHDL simulation you will get more insight. >>>> >>>> As previously mentioned the example is not functionally correct. The >>>> synthesis tools will catch this, especially VHDL because it is strongly >>>> typed. >>>> >>>>> >>>>> >>>>> wheras: >>>>> C.next[1:0] = A[0] + B[1] >>>>> >>>>> gets: >>>>> C(1-1 downto 0)<= (to_unsigned(A(0), 1) + to_unsigned(B(1), 1)); >>>>> and is synthesisable. >>>>> >>>> >>>> This one works because you provided enough bits for the result. As >>>> mentioned, the MyHDL simulation would flag the error. Verifying your >>>> module is a simple task. You should have test code that verifies your >>>> logic before trying conversion! >>>> >>>> >>>> .chris >>> >>> >>> Case1: >>> >>> C.next[1:0] = A[0] + B[1] >>> >>> Case2: >>> >>> C.next[0] = A[0] + B[1] >>> >>> Documentation says: >>> The Python convention of half-open ranges is followed: the bit with the >>> highest index is not included >>> (by the way in the documatation on the page 89 in the table there seems >>> to >>> be an error >>> bv[i:j] => slice of bv from i downto j -----> should be changed >>> to >>> bv[i:j] => slice of bv from i-1 downto j ) >>> >>> >>> The result intbv has the same length in both cases. And numberic_std >>> library says: >>> >>> function "+" (L, R: UNSIGNED) return UNSIGNED => "plus"; >>> -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). >>> >>> so the result length of an addition of two unsigned has the same length >>> as >>> the longest of the both operators and >>> the result type is a subtype of unsigned. >>> >>> greetings >>> >>> >> >> Let's backup a little. I think you have identified some areas for >> improvement but I don't think you have discovered something >> fundamentally broken. I believe your goal is to become more familiar >> with MyHDL and while trying it out you have found some items that you >> would like some clarification, correct? >> >> A couple examples might help. Your original and subsequent post had to >> do with bit assignments to an intbv. We can create examples for the >> bitwise operators and the numerical operators, run a simulation, and see >> what happens. And remove confusion by not using a module name that >> implies some functionality we are not trying to implement. >> >> ~~~[Code Example]~~~ >> from myhdl import * >> import traceback >> import sys >> >> def TryBitAssignXorOperator(a,b,c): >> >> @always_comb >> def hdl_assign(): >> c.next[0] = a[0] ^ b[0] >> >> return hdl_assign >> >> def TryBitAssignAddOperator(a,b,c): >> >> @always_comb >> def hdl_assign(): >> c.next[0] = a[0] + b[0] >> >> return hdl_assign >> >> def test(): >> >> Nbits = 3 >> a = Signal(intbv(0)[Nbits:]) >> b = Signal(intbv(0)[Nbits:]) >> c_xor = Signal(intbv(0)[Nbits:]) >> c_add = Signal(intbv(0)[Nbits:]) >> >> d_xor = TryBitAssignXorOperator(a,b,c_xor) >> d_add = TryBitAssignAddOperator(a,b,c_add) >> >> @instance >> def tb_stimulus(): >> for ii in xrange(2**Nbits): >> for jj in xrange(2**Nbits): >> a.next = ii >> b.next = jj >> yield delay(1) >> print("a:%s b:%s c_xor:%s c_add:%s" % \ >> (bin(a,Nbits), bin(b,Nbits), >> bin(c_xor,Nbits), >> bin(c_add,Nbits))) >> >> >> >> raise StopSimulation >> >> return d_xor, d_add, tb_stimulus >> >> if __name__ == '__main__': >> Simulation(test()).run() >> >> ~~~[End Code Example]~~~ >> >> ~~~[Output]~~~ >> a:000 b:000 c_xor:000 c_add:000 >> a:000 b:001 c_xor:001 c_add:001 >> a:000 b:010 c_xor:000 c_add:000 >> a:000 b:011 c_xor:001 c_add:001 >> a:000 b:100 c_xor:000 c_add:000 >> a:000 b:101 c_xor:001 c_add:001 >> a:000 b:110 c_xor:000 c_add:000 >> a:000 b:111 c_xor:001 c_add:001 >> a:001 b:000 c_xor:001 c_add:001 >> ... >> python2.7/site-packages/myhdl/_intbv.py", line 183, in __setitem__ >> " i == %s " % i >> ValueError: intbv[i] = v requires v in (0, 1) >> i == 0 >> >> ~~~[End Output]~~~ >> >> In this example you see that it fails the *add* when "a" and "b" are 1 >> (it doesn't print out a:001 b:001 because the exception occurs as soon >> as the assignment happens)! This is because the result of an intbv 1+1 >> requires two bits. An intbv is a constraint integer, it works more like >> VHDL signed/unsigned and not like std_logic_vector or Verilog's >> wire/reg. You can't do a single bit assignment to a value that requires >> more than 1 bit. >> >> It is my guess that the conversion doesn't handle this error case better >> because, usually, simulation is run and the error would be flagged in >> simulation. Hence, there has been no need to convert code like your >> example. >> >> What we can do is create an enhancement proposal that outlines a set of >> bit assign tests to extend to the conversion regression tests and >> specify useful error messages to be thrown if invalid conversion is >> attempted. I don't think this was the goal of your inquiry (was it?). >> But rather to get some more experience with MyHDL. >> >> In summary, what you are trying to do is invalid. Simulation will flag >> this correctly. >> >> Hope this helps, >> Chris > > > >> Let's backup a little. I think you have identified some areas for >> improvement but I don't think you have discovered something >> fundamentally broken. > > I have too admit that even the title of this topic -> "conversion error to > vhdl" is kind > of rough, because we are all (at least in my case) taught in school, high > school, whatever, that making an error > is not so good. And even if you dont read the title consciously, your > subconscious will put all the feelings and associations > forward which are connected to it. Since some of them have been in school > where we have been conditioned to errors such a title > can have an enormous effect. For example making the reader think, that the > writer think, that the reader have done something bad. > But i think the only bad errors which are made, are made by people on > purpose to hurt (in this or another way) someone. > And the other errors, kind of must be there as a source of improvement or > re-adjustment or whatsoever. So its about improvement. Not sure what this commentary is about. If you think you a detecting defensiveness, your not. I do find the MyHDL project useful and I am trying to contribute where I can. Jan Decaluwe has done a great job with MyHDL and improvements are the goal. On that note, Jan is the main developer and maintainer, and at this point all changes go through Jan. Jan is currently incommunicado, see this post, http://bit.ly/v0eI9C, for more information. > >> I believe your goal is to become more familiar >> with MyHDL > > true. > > > > Ok so what is about: > > c.next[0] = a[0] * b[0]<---- multiplikation instead of addition > > here the simulation runs successfully (100% testcoverage), and so the > conversion no warning and no errors diplayed > > this gets converted to > > c(0)<= to_std_logic(to_unsigned(a(0), 1) * to_unsigned(b(0), 1)); > > which is not synthesisable. The '*' is a valid example that fails. This should convert and a version of to_std_logic supporting unsigned should be added. But I don't think the change should be as simple as that. Per the previous discussions if the '+' is converted in the same matter the simulation and cosimulation (simulation of converted code) will not match. If the to_std_logic(unsigned) is to be added the non valid cases need to be caught and an error thrown. Which makes the change more complicated. > > > > The thing about the simulation is that if you have a unit with a lot of > inputs you cannot possible run > all number of combinations on the input. If you have internal registers > the thing gets even worse. So you can > only get a Testcoverage below 100%, so there is the change to actually > miss this case if you have an addition. This is kinda a can of worms. I don't think having a larger number of inputs is a good reason not to *test* with simulation. Yes, you might not ever be able to get 100% coverage. Which, in my mind, is a reason why you would not want the convert invalid code (the case of the '+'). Not obtaining 100% coverage is not a good reason not to achieve some coverage with simulation. > > Anyway it seem to be possible to get into a situation where the simulation > will run successfully (lets say 99% coverage or in the case of > the multiplikation even 100%), the conversion runs > successfully, but the generated code is not synthesisable. > I mean i like the fact that the bitwith of the operand of an addition is > automatically enhanced to create an extra bit for the overflow bit if the > code is generated in vhdl, but i think this should not necessarily include > that if you want to reduce the bitwith of the result by giving a > bitwith constraint to the result, that the conversion result is not valid. > > > > I think the easiest way to fix this is to just add a to_std_logic( a > unsigned ) to the pck_myhdl_07.vhd generator code. But, maybe this has > some other implications.? As discussed, the multiplication case is a valid error. This could be entered as a bug. The add/subtract doesn't hold as much water (converted HDL will not act the same as the MyHDL) but this can be an enhancement to throw an error instead of creating VHDL that will not compile/synthesize. We should also compare how the Verilog converter works but otherwise I think I am convinced that the to_std_logic(unsigned) should be added. We can make a patch but I think also a MEP should be created to address the '+'/'-'. If you want you can follow the guidelines here, http://bit.ly/ueKy5Y, and create a patch. Regards, Chris > > greetings Norbert > > > ------------------------------------------------------------------------------ > Cloud Services Checklist: Pricing and Packaging Optimization > This white paper is intended to serve as a reference, checklist and point of > discussion for anyone considering optimizing the pricing and packaging model > of a cloud services business. Read Now! > http://www.accelacomm.com/jaw/sfnl/114/51491232/ |
From: Norbo <Nor...@gm...> - 2011-12-06 14:12:57
|
On Sat, 03 Dec 2011 19:39:26 +0100, Christopher Felton <chr...@gm...> wrote: > On 11/30/11 9:52 AM, Norbo wrote: >> On Wed, 30 Nov 2011 13:39:25 +0100, Christopher Felton >> <chr...@gm...> wrote: >> >>> On 11/30/11 5:48 AM, Norbo wrote: >>>> On Wed, 23 Nov 2011 17:13:27 +0100, Christopher Felton >>>> <chr...@gm...> wrote: >>>> >>>>> On 11/22/11 3:15 PM, Norbo wrote: >>>>>> On Mon, 21 Nov 2011 17:28:05 +0100, Christopher Felton >>>>>> <chr...@gm...> wrote: >>>>>> >>>>>>> On 11/21/2011 8:52 AM, Oscar Diaz wrote: >>>>>>>> 2011/11/19 Norbo<Nor...@gm...>: >>>>>>>>> I have played a bit with myhdl and created the following: >>>>>>>>> >>>>>>>>> ---------------------------------------------------------- >>>>>>>>> from myhdl import * >>>>>>>>> >>>>>>>>> def bin2gray(A,B, C, width): >>>>>>>>> >>>>>>>>> """ Gray encoder. >>>>>>>>> >>>>>>>>> B -- input intbv signal, binary encoded >>>>>>>>> G -- output intbv signal, gray encoded >>>>>>>>> width -- bit width >>>>>>>>> >>>>>>>>> """ >>>>>>>>> @always_comb >>>>>>>>> def logic(): >>>>>>>>> C[0].next = A + B >>>>>>>> >>>>>>>> It seems that you have a bug here. Why you assign the result of a >>>>>>>> sum >>>>>>>> to a single bit? that's the reason why the converter tried to use >>>>>>>> "to_std_logic" for the output. If you want a normal sum, it should >>>>>>>> be >>>>>>>> >>>>>>>> C.next = A + B >>>>>>>> >>>>>>>> and the VHDL converter will put synthesizable code: >>>>>>>> >>>>>>>> C<= (A + B); >>>>>>>> >>>>>>> >>>>>>> Good eye Oscar! >>>>>>> >>>>>>> Yes, there are a couple issues with the bin2gray that was provided >>>>>>> (I >>>>>>> assumed the bin2gray was an example for conversion means and not an >>>>>>> actual bin2gray?). I didn't notice at first glance but if you want >>>>>>> to >>>>>>> assign a single bit of a bit-vector you need to do: >>>>>>> >>>>>>> C.next[0] = A + B >>>>>>> >>>>>>> >>>>>>> If you assign the bit correctly the conversion works (even though >>>>>>> it >>>>>>> functional doesn't work). Simulation will not work!. Not sure why >>>>>>> the >>>>>>> converter didn't flag this? Possible error detection enhancement. >>>>>>> >>>>>>> Also using the "+" operator instead of the bitwise "^" will cause >>>>>>> problems in simulation. The "+" will overflow the range for a >>>>>>> single >>>>>>> bit. >>>>>>> >>>>>>> My previous reply can be ignored and should be ignored. If any >>>>>>> changes >>>>>>> need to be made they would be in the error catching/reporting and >>>>>>> not >>>>>>> modifications to the conversion. >>>>>>> >>>>>>> Regards, >>>>>>> Chris >>>>>>> >>>>>>>> Or, if you want a binary to gray encoder, just use the example >>>>>>>> from >>>>>>>> the documentation >>>>>>>> >>>>>>>> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >>>>>>>> >>>>>>>> >>>>>>>> Best Regards >>>>>>>> >>>>>> >>>>>> Well the thing is: >>>>>> >>>>>> If i write: >>>>>> >>>>>> C[4:0].next = A+B in vhdl it gets -> C(4-1 downto 0)<= >>>>>> resize(A >>>>>> + >>>>>> B,4); >>>>>> >>>>>> or: >>>>>> >>>>>> C[1:0].next = A+B in vhdl it gets -> C(1-1 downto 0)<= >>>>>> resize(A + >>>>>> B,1); >>>>>> which in in my understanding this makes kind of sense because the >>>>>> result >>>>>> is cropped to the output size. (maybe a warning would be nice, but >>>>>> it >>>>>> could be difficult if the calculation gets longer) >>>>>> >>>>>> >>>>>> but when i write : >>>>>> >>>>>> C[0].next = A+B >>>>>> (which is actually the same as the above C[1:0].next = A+B) >>>>>> in vhdl it gets -> C(0)<= to_std_logic(A + B); >>>>>> and is not synthesisable. >>>>>> >>>>>> >>>>> >>>>> As mentioned, the above is the incorrect syntax. The converted >>>>> results >>>>> are unreliable. To do bit indexing you need to do: >>>>> >>>>> C.next[0] = A[0] + B[1] >>>>> >>>>> If you do C[0].next that is used for a list of signals. If you run a >>>>> simulation (testbench) this error will be identified. >>>>> >>>>> Review the following links: >>>>> http://www.myhdl.org/doc/current/manual/intro.html#bit-indexing >>>>> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >>>>> >>>>> Also, run a simple simulation. That will give you some more insight >>>>> into the issue. >>>>> >>>>> Regards, >>>>> Chris >>>> >>>> Sorry that i keep bagging, i really like myhdl and i really want to >>>> get >>>> it >>>> better >>>> so if i write: >>>> >>>> C.next[0] = A[0] + B[1] >>>> >>>> the line which is produced is: >>>> >>>> C(0)<= to_std_logic(to_unsigned(A(0), 1) + to_unsigned(B(0), 1)); >>>> >>>> and it is not synthesisable because of the to_std_logic. >>> >>> Correct, the conversion generated an equivilant assignment. Which is >>> not synthesizable (it is syntactically correct and will compile with a >>> VHDL simulator). But the two statements are equivalent. If you run a >>> MyHDL simulation you will get more insight. >>> >>> As previously mentioned the example is not functionally correct. The >>> synthesis tools will catch this, especially VHDL because it is strongly >>> typed. >>> >>>> >>>> >>>> wheras: >>>> C.next[1:0] = A[0] + B[1] >>>> >>>> gets: >>>> C(1-1 downto 0)<= (to_unsigned(A(0), 1) + to_unsigned(B(1), 1)); >>>> and is synthesisable. >>>> >>> >>> This one works because you provided enough bits for the result. As >>> mentioned, the MyHDL simulation would flag the error. Verifying your >>> module is a simple task. You should have test code that verifies your >>> logic before trying conversion! >>> >>> >>> .chris >> >> >> Case1: >> >> C.next[1:0] = A[0] + B[1] >> >> Case2: >> >> C.next[0] = A[0] + B[1] >> >> Documentation says: >> The Python convention of half-open ranges is followed: the bit with the >> highest index is not included >> (by the way in the documatation on the page 89 in the table there seems >> to >> be an error >> bv[i:j] => slice of bv from i downto j -----> should be changed >> to >> bv[i:j] => slice of bv from i-1 downto j ) >> >> >> The result intbv has the same length in both cases. And numberic_std >> library says: >> >> function "+" (L, R: UNSIGNED) return UNSIGNED => "plus"; >> -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). >> >> so the result length of an addition of two unsigned has the same length >> as >> the longest of the both operators and >> the result type is a subtype of unsigned. >> >> greetings >> >> > > Let's backup a little. I think you have identified some areas for > improvement but I don't think you have discovered something > fundamentally broken. I believe your goal is to become more familiar > with MyHDL and while trying it out you have found some items that you > would like some clarification, correct? > > A couple examples might help. Your original and subsequent post had to > do with bit assignments to an intbv. We can create examples for the > bitwise operators and the numerical operators, run a simulation, and see > what happens. And remove confusion by not using a module name that > implies some functionality we are not trying to implement. > > ~~~[Code Example]~~~ > from myhdl import * > import traceback > import sys > > def TryBitAssignXorOperator(a,b,c): > > @always_comb > def hdl_assign(): > c.next[0] = a[0] ^ b[0] > > return hdl_assign > > def TryBitAssignAddOperator(a,b,c): > > @always_comb > def hdl_assign(): > c.next[0] = a[0] + b[0] > > return hdl_assign > > def test(): > > Nbits = 3 > a = Signal(intbv(0)[Nbits:]) > b = Signal(intbv(0)[Nbits:]) > c_xor = Signal(intbv(0)[Nbits:]) > c_add = Signal(intbv(0)[Nbits:]) > > d_xor = TryBitAssignXorOperator(a,b,c_xor) > d_add = TryBitAssignAddOperator(a,b,c_add) > > @instance > def tb_stimulus(): > for ii in xrange(2**Nbits): > for jj in xrange(2**Nbits): > a.next = ii > b.next = jj > yield delay(1) > print("a:%s b:%s c_xor:%s c_add:%s" % \ > (bin(a,Nbits), bin(b,Nbits), > bin(c_xor,Nbits), > bin(c_add,Nbits))) > > > > raise StopSimulation > > return d_xor, d_add, tb_stimulus > > if __name__ == '__main__': > Simulation(test()).run() > > ~~~[End Code Example]~~~ > > ~~~[Output]~~~ > a:000 b:000 c_xor:000 c_add:000 > a:000 b:001 c_xor:001 c_add:001 > a:000 b:010 c_xor:000 c_add:000 > a:000 b:011 c_xor:001 c_add:001 > a:000 b:100 c_xor:000 c_add:000 > a:000 b:101 c_xor:001 c_add:001 > a:000 b:110 c_xor:000 c_add:000 > a:000 b:111 c_xor:001 c_add:001 > a:001 b:000 c_xor:001 c_add:001 > ... > python2.7/site-packages/myhdl/_intbv.py", line 183, in __setitem__ > " i == %s " % i > ValueError: intbv[i] = v requires v in (0, 1) > i == 0 > > ~~~[End Output]~~~ > > In this example you see that it fails the *add* when "a" and "b" are 1 > (it doesn't print out a:001 b:001 because the exception occurs as soon > as the assignment happens)! This is because the result of an intbv 1+1 > requires two bits. An intbv is a constraint integer, it works more like > VHDL signed/unsigned and not like std_logic_vector or Verilog's > wire/reg. You can't do a single bit assignment to a value that requires > more than 1 bit. > > It is my guess that the conversion doesn't handle this error case better > because, usually, simulation is run and the error would be flagged in > simulation. Hence, there has been no need to convert code like your > example. > > What we can do is create an enhancement proposal that outlines a set of > bit assign tests to extend to the conversion regression tests and > specify useful error messages to be thrown if invalid conversion is > attempted. I don't think this was the goal of your inquiry (was it?). > But rather to get some more experience with MyHDL. > > In summary, what you are trying to do is invalid. Simulation will flag > this correctly. > > Hope this helps, > Chris > Let's backup a little. I think you have identified some areas for > improvement but I don't think you have discovered something > fundamentally broken. I have too admit that even the title of this topic -> "conversion error to vhdl" is kind of rough, because we are all (at least in my case) taught in school, high school, whatever, that making an error is not so good. And even if you dont read the title consciously, your subconscious will put all the feelings and associations forward which are connected to it. Since some of them have been in school where we have been conditioned to errors such a title can have an enormous effect. For example making the reader think, that the writer think, that the reader have done something bad. But i think the only bad errors which are made, are made by people on purpose to hurt (in this or another way) someone. And the other errors, kind of must be there as a source of improvement or re-adjustment or whatsoever. So its about improvement. > I believe your goal is to become more familiar > with MyHDL true. Ok so what is about: c.next[0] = a[0] * b[0] <---- multiplikation instead of addition here the simulation runs successfully (100% testcoverage), and so the conversion no warning and no errors diplayed this gets converted to c(0) <= to_std_logic(to_unsigned(a(0), 1) * to_unsigned(b(0), 1)); which is not synthesisable. The thing about the simulation is that if you have a unit with a lot of inputs you cannot possible run all number of combinations on the input. If you have internal registers the thing gets even worse. So you can only get a Testcoverage below 100%, so there is the change to actually miss this case if you have an addition. Anyway it seem to be possible to get into a situation where the simulation will run successfully (lets say 99% coverage or in the case of the multiplikation even 100%), the conversion runs successfully, but the generated code is not synthesisable. I mean i like the fact that the bitwith of the operand of an addition is automatically enhanced to create an extra bit for the overflow bit if the code is generated in vhdl, but i think this should not necessarily include that if you want to reduce the bitwith of the result by giving a bitwith constraint to the result, that the conversion result is not valid. I think the easiest way to fix this is to just add a to_std_logic( a unsigned ) to the pck_myhdl_07.vhd generator code. But, maybe this has some other implications.? greetings Norbert |
From: Christopher F. <chr...@gm...> - 2011-12-03 18:40:02
|
On 11/30/11 9:52 AM, Norbo wrote: > On Wed, 30 Nov 2011 13:39:25 +0100, Christopher Felton > <chr...@gm...> wrote: > >> On 11/30/11 5:48 AM, Norbo wrote: >>> On Wed, 23 Nov 2011 17:13:27 +0100, Christopher Felton >>> <chr...@gm...> wrote: >>> >>>> On 11/22/11 3:15 PM, Norbo wrote: >>>>> On Mon, 21 Nov 2011 17:28:05 +0100, Christopher Felton >>>>> <chr...@gm...> wrote: >>>>> >>>>>> On 11/21/2011 8:52 AM, Oscar Diaz wrote: >>>>>>> 2011/11/19 Norbo<Nor...@gm...>: >>>>>>>> I have played a bit with myhdl and created the following: >>>>>>>> >>>>>>>> ---------------------------------------------------------- >>>>>>>> from myhdl import * >>>>>>>> >>>>>>>> def bin2gray(A,B, C, width): >>>>>>>> >>>>>>>> """ Gray encoder. >>>>>>>> >>>>>>>> B -- input intbv signal, binary encoded >>>>>>>> G -- output intbv signal, gray encoded >>>>>>>> width -- bit width >>>>>>>> >>>>>>>> """ >>>>>>>> @always_comb >>>>>>>> def logic(): >>>>>>>> C[0].next = A + B >>>>>>> >>>>>>> It seems that you have a bug here. Why you assign the result of a >>>>>>> sum >>>>>>> to a single bit? that's the reason why the converter tried to use >>>>>>> "to_std_logic" for the output. If you want a normal sum, it should >>>>>>> be >>>>>>> >>>>>>> C.next = A + B >>>>>>> >>>>>>> and the VHDL converter will put synthesizable code: >>>>>>> >>>>>>> C<= (A + B); >>>>>>> >>>>>> >>>>>> Good eye Oscar! >>>>>> >>>>>> Yes, there are a couple issues with the bin2gray that was provided (I >>>>>> assumed the bin2gray was an example for conversion means and not an >>>>>> actual bin2gray?). I didn't notice at first glance but if you want >>>>>> to >>>>>> assign a single bit of a bit-vector you need to do: >>>>>> >>>>>> C.next[0] = A + B >>>>>> >>>>>> >>>>>> If you assign the bit correctly the conversion works (even though it >>>>>> functional doesn't work). Simulation will not work!. Not sure why >>>>>> the >>>>>> converter didn't flag this? Possible error detection enhancement. >>>>>> >>>>>> Also using the "+" operator instead of the bitwise "^" will cause >>>>>> problems in simulation. The "+" will overflow the range for a single >>>>>> bit. >>>>>> >>>>>> My previous reply can be ignored and should be ignored. If any >>>>>> changes >>>>>> need to be made they would be in the error catching/reporting and not >>>>>> modifications to the conversion. >>>>>> >>>>>> Regards, >>>>>> Chris >>>>>> >>>>>>> Or, if you want a binary to gray encoder, just use the example from >>>>>>> the documentation >>>>>>> >>>>>>> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >>>>>>> >>>>>>> >>>>>>> Best Regards >>>>>>> >>>>> >>>>> Well the thing is: >>>>> >>>>> If i write: >>>>> >>>>> C[4:0].next = A+B in vhdl it gets -> C(4-1 downto 0)<= resize(A >>>>> + >>>>> B,4); >>>>> >>>>> or: >>>>> >>>>> C[1:0].next = A+B in vhdl it gets -> C(1-1 downto 0)<= resize(A + >>>>> B,1); >>>>> which in in my understanding this makes kind of sense because the >>>>> result >>>>> is cropped to the output size. (maybe a warning would be nice, but it >>>>> could be difficult if the calculation gets longer) >>>>> >>>>> >>>>> but when i write : >>>>> >>>>> C[0].next = A+B >>>>> (which is actually the same as the above C[1:0].next = A+B) >>>>> in vhdl it gets -> C(0)<= to_std_logic(A + B); >>>>> and is not synthesisable. >>>>> >>>>> >>>> >>>> As mentioned, the above is the incorrect syntax. The converted results >>>> are unreliable. To do bit indexing you need to do: >>>> >>>> C.next[0] = A[0] + B[1] >>>> >>>> If you do C[0].next that is used for a list of signals. If you run a >>>> simulation (testbench) this error will be identified. >>>> >>>> Review the following links: >>>> http://www.myhdl.org/doc/current/manual/intro.html#bit-indexing >>>> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >>>> >>>> Also, run a simple simulation. That will give you some more insight >>>> into the issue. >>>> >>>> Regards, >>>> Chris >>> >>> Sorry that i keep bagging, i really like myhdl and i really want to get >>> it >>> better >>> so if i write: >>> >>> C.next[0] = A[0] + B[1] >>> >>> the line which is produced is: >>> >>> C(0)<= to_std_logic(to_unsigned(A(0), 1) + to_unsigned(B(0), 1)); >>> >>> and it is not synthesisable because of the to_std_logic. >> >> Correct, the conversion generated an equivilant assignment. Which is >> not synthesizable (it is syntactically correct and will compile with a >> VHDL simulator). But the two statements are equivalent. If you run a >> MyHDL simulation you will get more insight. >> >> As previously mentioned the example is not functionally correct. The >> synthesis tools will catch this, especially VHDL because it is strongly >> typed. >> >>> >>> >>> wheras: >>> C.next[1:0] = A[0] + B[1] >>> >>> gets: >>> C(1-1 downto 0)<= (to_unsigned(A(0), 1) + to_unsigned(B(1), 1)); >>> and is synthesisable. >>> >> >> This one works because you provided enough bits for the result. As >> mentioned, the MyHDL simulation would flag the error. Verifying your >> module is a simple task. You should have test code that verifies your >> logic before trying conversion! >> >> >> .chris > > > Case1: > > C.next[1:0] = A[0] + B[1] > > Case2: > > C.next[0] = A[0] + B[1] > > Documentation says: > The Python convention of half-open ranges is followed: the bit with the > highest index is not included > (by the way in the documatation on the page 89 in the table there seems to > be an error > bv[i:j] => slice of bv from i downto j -----> should be changed to > bv[i:j] => slice of bv from i-1 downto j ) > > > The result intbv has the same length in both cases. And numberic_std > library says: > > function "+" (L, R: UNSIGNED) return UNSIGNED => "plus"; > -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). > > so the result length of an addition of two unsigned has the same length as > the longest of the both operators and > the result type is a subtype of unsigned. > > greetings > > Let's backup a little. I think you have identified some areas for improvement but I don't think you have discovered something fundamentally broken. I believe your goal is to become more familiar with MyHDL and while trying it out you have found some items that you would like some clarification, correct? A couple examples might help. Your original and subsequent post had to do with bit assignments to an intbv. We can create examples for the bitwise operators and the numerical operators, run a simulation, and see what happens. And remove confusion by not using a module name that implies some functionality we are not trying to implement. ~~~[Code Example]~~~ from myhdl import * import traceback import sys def TryBitAssignXorOperator(a,b,c): @always_comb def hdl_assign(): c.next[0] = a[0] ^ b[0] return hdl_assign def TryBitAssignAddOperator(a,b,c): @always_comb def hdl_assign(): c.next[0] = a[0] + b[0] return hdl_assign def test(): Nbits = 3 a = Signal(intbv(0)[Nbits:]) b = Signal(intbv(0)[Nbits:]) c_xor = Signal(intbv(0)[Nbits:]) c_add = Signal(intbv(0)[Nbits:]) d_xor = TryBitAssignXorOperator(a,b,c_xor) d_add = TryBitAssignAddOperator(a,b,c_add) @instance def tb_stimulus(): for ii in xrange(2**Nbits): for jj in xrange(2**Nbits): a.next = ii b.next = jj yield delay(1) print("a:%s b:%s c_xor:%s c_add:%s" % \ (bin(a,Nbits), bin(b,Nbits), bin(c_xor,Nbits), bin(c_add,Nbits))) raise StopSimulation return d_xor, d_add, tb_stimulus if __name__ == '__main__': Simulation(test()).run() ~~~[End Code Example]~~~ ~~~[Output]~~~ a:000 b:000 c_xor:000 c_add:000 a:000 b:001 c_xor:001 c_add:001 a:000 b:010 c_xor:000 c_add:000 a:000 b:011 c_xor:001 c_add:001 a:000 b:100 c_xor:000 c_add:000 a:000 b:101 c_xor:001 c_add:001 a:000 b:110 c_xor:000 c_add:000 a:000 b:111 c_xor:001 c_add:001 a:001 b:000 c_xor:001 c_add:001 ... python2.7/site-packages/myhdl/_intbv.py", line 183, in __setitem__ " i == %s " % i ValueError: intbv[i] = v requires v in (0, 1) i == 0 ~~~[End Output]~~~ In this example you see that it fails the *add* when "a" and "b" are 1 (it doesn't print out a:001 b:001 because the exception occurs as soon as the assignment happens)! This is because the result of an intbv 1+1 requires two bits. An intbv is a constraint integer, it works more like VHDL signed/unsigned and not like std_logic_vector or Verilog's wire/reg. You can't do a single bit assignment to a value that requires more than 1 bit. It is my guess that the conversion doesn't handle this error case better because, usually, simulation is run and the error would be flagged in simulation. Hence, there has been no need to convert code like your example. What we can do is create an enhancement proposal that outlines a set of bit assign tests to extend to the conversion regression tests and specify useful error messages to be thrown if invalid conversion is attempted. I don't think this was the goal of your inquiry (was it?). But rather to get some more experience with MyHDL. In summary, what you are trying to do is invalid. Simulation will flag this correctly. Hope this helps, Chris |
From: Norbo <Nor...@gm...> - 2011-11-30 15:53:13
|
On Wed, 30 Nov 2011 13:39:25 +0100, Christopher Felton <chr...@gm...> wrote: > On 11/30/11 5:48 AM, Norbo wrote: >> On Wed, 23 Nov 2011 17:13:27 +0100, Christopher Felton >> <chr...@gm...> wrote: >> >>> On 11/22/11 3:15 PM, Norbo wrote: >>>> On Mon, 21 Nov 2011 17:28:05 +0100, Christopher Felton >>>> <chr...@gm...> wrote: >>>> >>>>> On 11/21/2011 8:52 AM, Oscar Diaz wrote: >>>>>> 2011/11/19 Norbo<Nor...@gm...>: >>>>>>> I have played a bit with myhdl and created the following: >>>>>>> >>>>>>> ---------------------------------------------------------- >>>>>>> from myhdl import * >>>>>>> >>>>>>> def bin2gray(A,B, C, width): >>>>>>> >>>>>>> """ Gray encoder. >>>>>>> >>>>>>> B -- input intbv signal, binary encoded >>>>>>> G -- output intbv signal, gray encoded >>>>>>> width -- bit width >>>>>>> >>>>>>> """ >>>>>>> @always_comb >>>>>>> def logic(): >>>>>>> C[0].next = A + B >>>>>> >>>>>> It seems that you have a bug here. Why you assign the result of a >>>>>> sum >>>>>> to a single bit? that's the reason why the converter tried to use >>>>>> "to_std_logic" for the output. If you want a normal sum, it should >>>>>> be >>>>>> >>>>>> C.next = A + B >>>>>> >>>>>> and the VHDL converter will put synthesizable code: >>>>>> >>>>>> C<= (A + B); >>>>>> >>>>> >>>>> Good eye Oscar! >>>>> >>>>> Yes, there are a couple issues with the bin2gray that was provided (I >>>>> assumed the bin2gray was an example for conversion means and not an >>>>> actual bin2gray?). I didn't notice at first glance but if you want >>>>> to >>>>> assign a single bit of a bit-vector you need to do: >>>>> >>>>> C.next[0] = A + B >>>>> >>>>> >>>>> If you assign the bit correctly the conversion works (even though it >>>>> functional doesn't work). Simulation will not work!. Not sure why >>>>> the >>>>> converter didn't flag this? Possible error detection enhancement. >>>>> >>>>> Also using the "+" operator instead of the bitwise "^" will cause >>>>> problems in simulation. The "+" will overflow the range for a single >>>>> bit. >>>>> >>>>> My previous reply can be ignored and should be ignored. If any >>>>> changes >>>>> need to be made they would be in the error catching/reporting and not >>>>> modifications to the conversion. >>>>> >>>>> Regards, >>>>> Chris >>>>> >>>>>> Or, if you want a binary to gray encoder, just use the example from >>>>>> the documentation >>>>>> >>>>>> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >>>>>> >>>>>> >>>>>> Best Regards >>>>>> >>>> >>>> Well the thing is: >>>> >>>> If i write: >>>> >>>> C[4:0].next = A+B in vhdl it gets -> C(4-1 downto 0)<= resize(A >>>> + >>>> B,4); >>>> >>>> or: >>>> >>>> C[1:0].next = A+B in vhdl it gets -> C(1-1 downto 0)<= resize(A + >>>> B,1); >>>> which in in my understanding this makes kind of sense because the >>>> result >>>> is cropped to the output size. (maybe a warning would be nice, but it >>>> could be difficult if the calculation gets longer) >>>> >>>> >>>> but when i write : >>>> >>>> C[0].next = A+B >>>> (which is actually the same as the above C[1:0].next = A+B) >>>> in vhdl it gets -> C(0)<= to_std_logic(A + B); >>>> and is not synthesisable. >>>> >>>> >>> >>> As mentioned, the above is the incorrect syntax. The converted results >>> are unreliable. To do bit indexing you need to do: >>> >>> C.next[0] = A[0] + B[1] >>> >>> If you do C[0].next that is used for a list of signals. If you run a >>> simulation (testbench) this error will be identified. >>> >>> Review the following links: >>> http://www.myhdl.org/doc/current/manual/intro.html#bit-indexing >>> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >>> >>> Also, run a simple simulation. That will give you some more insight >>> into the issue. >>> >>> Regards, >>> Chris >> >> Sorry that i keep bagging, i really like myhdl and i really want to get >> it >> better >> so if i write: >> >> C.next[0] = A[0] + B[1] >> >> the line which is produced is: >> >> C(0)<= to_std_logic(to_unsigned(A(0), 1) + to_unsigned(B(0), 1)); >> >> and it is not synthesisable because of the to_std_logic. > > Correct, the conversion generated an equivilant assignment. Which is > not synthesizable (it is syntactically correct and will compile with a > VHDL simulator). But the two statements are equivalent. If you run a > MyHDL simulation you will get more insight. > > As previously mentioned the example is not functionally correct. The > synthesis tools will catch this, especially VHDL because it is strongly > typed. > >> >> >> wheras: >> C.next[1:0] = A[0] + B[1] >> >> gets: >> C(1-1 downto 0)<= (to_unsigned(A(0), 1) + to_unsigned(B(1), 1)); >> and is synthesisable. >> > > This one works because you provided enough bits for the result. As > mentioned, the MyHDL simulation would flag the error. Verifying your > module is a simple task. You should have test code that verifies your > logic before trying conversion! > > > .chris Case1: C.next[1:0] = A[0] + B[1] Case2: C.next[0] = A[0] + B[1] Documentation says: The Python convention of half-open ranges is followed: the bit with the highest index is not included (by the way in the documatation on the page 89 in the table there seems to be an error bv[i:j] => slice of bv from i downto j -----> should be changed to bv[i:j] => slice of bv from i-1 downto j ) The result intbv has the same length in both cases. And numberic_std library says: function "+" (L, R: UNSIGNED) return UNSIGNED => "plus"; -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). so the result length of an addition of two unsigned has the same length as the longest of the both operators and the result type is a subtype of unsigned. greetings -- Using Opera's revolutionary email client: http://www.opera.com/mail/ |
From: Christopher F. <chr...@gm...> - 2011-11-30 12:39:57
|
On 11/30/11 5:48 AM, Norbo wrote: > On Wed, 23 Nov 2011 17:13:27 +0100, Christopher Felton > <chr...@gm...> wrote: > >> On 11/22/11 3:15 PM, Norbo wrote: >>> On Mon, 21 Nov 2011 17:28:05 +0100, Christopher Felton >>> <chr...@gm...> wrote: >>> >>>> On 11/21/2011 8:52 AM, Oscar Diaz wrote: >>>>> 2011/11/19 Norbo<Nor...@gm...>: >>>>>> I have played a bit with myhdl and created the following: >>>>>> >>>>>> ---------------------------------------------------------- >>>>>> from myhdl import * >>>>>> >>>>>> def bin2gray(A,B, C, width): >>>>>> >>>>>> """ Gray encoder. >>>>>> >>>>>> B -- input intbv signal, binary encoded >>>>>> G -- output intbv signal, gray encoded >>>>>> width -- bit width >>>>>> >>>>>> """ >>>>>> @always_comb >>>>>> def logic(): >>>>>> C[0].next = A + B >>>>> >>>>> It seems that you have a bug here. Why you assign the result of a sum >>>>> to a single bit? that's the reason why the converter tried to use >>>>> "to_std_logic" for the output. If you want a normal sum, it should be >>>>> >>>>> C.next = A + B >>>>> >>>>> and the VHDL converter will put synthesizable code: >>>>> >>>>> C<= (A + B); >>>>> >>>> >>>> Good eye Oscar! >>>> >>>> Yes, there are a couple issues with the bin2gray that was provided (I >>>> assumed the bin2gray was an example for conversion means and not an >>>> actual bin2gray?). I didn't notice at first glance but if you want to >>>> assign a single bit of a bit-vector you need to do: >>>> >>>> C.next[0] = A + B >>>> >>>> >>>> If you assign the bit correctly the conversion works (even though it >>>> functional doesn't work). Simulation will not work!. Not sure why the >>>> converter didn't flag this? Possible error detection enhancement. >>>> >>>> Also using the "+" operator instead of the bitwise "^" will cause >>>> problems in simulation. The "+" will overflow the range for a single >>>> bit. >>>> >>>> My previous reply can be ignored and should be ignored. If any changes >>>> need to be made they would be in the error catching/reporting and not >>>> modifications to the conversion. >>>> >>>> Regards, >>>> Chris >>>> >>>>> Or, if you want a binary to gray encoder, just use the example from >>>>> the documentation >>>>> >>>>> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >>>>> >>>>> >>>>> Best Regards >>>>> >>> >>> Well the thing is: >>> >>> If i write: >>> >>> C[4:0].next = A+B in vhdl it gets -> C(4-1 downto 0)<= resize(A + >>> B,4); >>> >>> or: >>> >>> C[1:0].next = A+B in vhdl it gets -> C(1-1 downto 0)<= resize(A + >>> B,1); >>> which in in my understanding this makes kind of sense because the >>> result >>> is cropped to the output size. (maybe a warning would be nice, but it >>> could be difficult if the calculation gets longer) >>> >>> >>> but when i write : >>> >>> C[0].next = A+B >>> (which is actually the same as the above C[1:0].next = A+B) >>> in vhdl it gets -> C(0)<= to_std_logic(A + B); >>> and is not synthesisable. >>> >>> >> >> As mentioned, the above is the incorrect syntax. The converted results >> are unreliable. To do bit indexing you need to do: >> >> C.next[0] = A[0] + B[1] >> >> If you do C[0].next that is used for a list of signals. If you run a >> simulation (testbench) this error will be identified. >> >> Review the following links: >> http://www.myhdl.org/doc/current/manual/intro.html#bit-indexing >> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >> >> Also, run a simple simulation. That will give you some more insight >> into the issue. >> >> Regards, >> Chris > > Sorry that i keep bagging, i really like myhdl and i really want to get it > better > so if i write: > > C.next[0] = A[0] + B[1] > > the line which is produced is: > > C(0)<= to_std_logic(to_unsigned(A(0), 1) + to_unsigned(B(0), 1)); > > and it is not synthesisable because of the to_std_logic. Correct, the conversion generated an equivilant assignment. Which is not synthesizable (it is syntactically correct and will compile with a VHDL simulator). But the two statements are equivalent. If you run a MyHDL simulation you will get more insight. As previously mentioned the example is not functionally correct. The synthesis tools will catch this, especially VHDL because it is strongly typed. > > > wheras: > C.next[1:0] = A[0] + B[1] > > gets: > C(1-1 downto 0)<= (to_unsigned(A(0), 1) + to_unsigned(B(1), 1)); > and is synthesisable. > This one works because you provided enough bits for the result. As mentioned, the MyHDL simulation would flag the error. Verifying your module is a simple task. You should have test code that verifies your logic before trying conversion! .chris > > thanks in advance > > > > ------------------------------------------------------------------------------ > All the data continuously generated in your IT infrastructure > contains a definitive record of customers, application performance, > security threats, fraudulent activity, and more. Splunk takes this > data and makes sense of it. IT sense. And common sense. > http://p.sf.net/sfu/splunk-novd2d |
From: Norbo <Nor...@gm...> - 2011-11-30 11:48:34
|
On Wed, 23 Nov 2011 17:13:27 +0100, Christopher Felton <chr...@gm...> wrote: > On 11/22/11 3:15 PM, Norbo wrote: >> On Mon, 21 Nov 2011 17:28:05 +0100, Christopher Felton >> <chr...@gm...> wrote: >> >>> On 11/21/2011 8:52 AM, Oscar Diaz wrote: >>>> 2011/11/19 Norbo<Nor...@gm...>: >>>>> I have played a bit with myhdl and created the following: >>>>> >>>>> ---------------------------------------------------------- >>>>> from myhdl import * >>>>> >>>>> def bin2gray(A,B, C, width): >>>>> >>>>> """ Gray encoder. >>>>> >>>>> B -- input intbv signal, binary encoded >>>>> G -- output intbv signal, gray encoded >>>>> width -- bit width >>>>> >>>>> """ >>>>> @always_comb >>>>> def logic(): >>>>> C[0].next = A + B >>>> >>>> It seems that you have a bug here. Why you assign the result of a sum >>>> to a single bit? that's the reason why the converter tried to use >>>> "to_std_logic" for the output. If you want a normal sum, it should be >>>> >>>> C.next = A + B >>>> >>>> and the VHDL converter will put synthesizable code: >>>> >>>> C<= (A + B); >>>> >>> >>> Good eye Oscar! >>> >>> Yes, there are a couple issues with the bin2gray that was provided (I >>> assumed the bin2gray was an example for conversion means and not an >>> actual bin2gray?). I didn't notice at first glance but if you want to >>> assign a single bit of a bit-vector you need to do: >>> >>> C.next[0] = A + B >>> >>> >>> If you assign the bit correctly the conversion works (even though it >>> functional doesn't work). Simulation will not work!. Not sure why the >>> converter didn't flag this? Possible error detection enhancement. >>> >>> Also using the "+" operator instead of the bitwise "^" will cause >>> problems in simulation. The "+" will overflow the range for a single >>> bit. >>> >>> My previous reply can be ignored and should be ignored. If any changes >>> need to be made they would be in the error catching/reporting and not >>> modifications to the conversion. >>> >>> Regards, >>> Chris >>> >>>> Or, if you want a binary to gray encoder, just use the example from >>>> the documentation >>>> >>>> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >>>> >>>> >>>> Best Regards >>>> >> >> Well the thing is: >> >> If i write: >> >> C[4:0].next = A+B in vhdl it gets -> C(4-1 downto 0)<= resize(A + >> B,4); >> >> or: >> >> C[1:0].next = A+B in vhdl it gets -> C(1-1 downto 0)<= resize(A + >> B,1); >> which in in my understanding this makes kind of sense because the >> result >> is cropped to the output size. (maybe a warning would be nice, but it >> could be difficult if the calculation gets longer) >> >> >> but when i write : >> >> C[0].next = A+B >> (which is actually the same as the above C[1:0].next = A+B) >> in vhdl it gets -> C(0)<= to_std_logic(A + B); >> and is not synthesisable. >> >> > > As mentioned, the above is the incorrect syntax. The converted results > are unreliable. To do bit indexing you need to do: > > C.next[0] = A[0] + B[1] > > If you do C[0].next that is used for a list of signals. If you run a > simulation (testbench) this error will be identified. > > Review the following links: > http://www.myhdl.org/doc/current/manual/intro.html#bit-indexing > http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design > > Also, run a simple simulation. That will give you some more insight > into the issue. > > Regards, > Chris Sorry that i keep bagging, i really like myhdl and i really want to get it better so if i write: C.next[0] = A[0] + B[1] the line which is produced is: C(0) <= to_std_logic(to_unsigned(A(0), 1) + to_unsigned(B(0), 1)); and it is not synthesisable because of the to_std_logic. wheras: C.next[1:0] = A[0] + B[1] gets: C(1-1 downto 0) <= (to_unsigned(A(0), 1) + to_unsigned(B(1), 1)); and is synthesisable. thanks in advance |
From: garyr <ga...@fi...> - 2011-11-23 20:23:57
|
----- Original Message ----- From: "Christopher Felton" <chr...@gm...> To: <myh...@li...> Sent: Wednesday, November 23, 2011 9:09 AM Subject: Re: [myhdl-list] Signal has multiple drivers > On 11/22/11 6:29 PM, garyr wrote: >> Code that appears to be OK when simulated produces errors "Signal has >> multiple drivers" when I attempt to convert it to Verilog. In my case the >> two drivers never access the signal at the same time so there should be >> no >> problem. Google didn't turn up any useful information. >> >> In one case a rather simple change eliminated the problem. Another >> occurrence I eliminated by adding a multiplexer that routed a start and >> an >> 8-bit command signal to the shared module. A third occurrence involves an >> unsigned division module having 32-bit parameters dividend, divisor and >> quotient. The dividend and divisor signals would have multiple drivers. >> Using a multiplexer approach here would be very costly in terms of bits. >> Is >> there some other way of dealing with this problem? Couldn't MyHDL just >> issue >> a warning? >> >> > > You can not have multiple drivers if you wish to have a physical > realization of the circuit. The circuits are always driving their > outputs, in the physical circuit -without including tri-states, mux, > etc- there isn't the notion of not driving an output. Depending on the > type of source and sinks in the technology you could implement "wire > and" and "wire or" but I am unaware of any tools (synthesis, par) that > will support multiple drivers. > > If you wish to have a physical realization of your circuit description > you will need to define how the outputs are arbitrated. This could be > as simple as "or"ing the outputs together but it depends on your circuit. > > Simulation allows multiple drivers so you can easily do things in > testbenches, portions of the HDL that are not intended to be > synthesized. This is is the same in Verilog and VHDL. Multiple drivers > are not part of the synthesizable subset. Even if MyHDL were to let > this pass you would fail when you try and synthesize the underlying HDL. > > Hope that helps, > Chris > > > ------------------------------------------------------------------------------ > All the data continuously generated in your IT infrastructure > contains a definitive record of customers, application performance, > security threats, fraudulent activity, and more. Splunk takes this > data and makes sense of it. IT sense. And common sense. > http://p.sf.net/sfu/splunk-novd2d > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > It helped a lot. Thanks for the explanation. Gary Richardson |
From: Christopher F. <chr...@gm...> - 2011-11-23 17:10:11
|
On 11/22/11 6:29 PM, garyr wrote: > Code that appears to be OK when simulated produces errors "Signal has > multiple drivers" when I attempt to convert it to Verilog. In my case the > two drivers never access the signal at the same time so there should be no > problem. Google didn't turn up any useful information. > > In one case a rather simple change eliminated the problem. Another > occurrence I eliminated by adding a multiplexer that routed a start and an > 8-bit command signal to the shared module. A third occurrence involves an > unsigned division module having 32-bit parameters dividend, divisor and > quotient. The dividend and divisor signals would have multiple drivers. > Using a multiplexer approach here would be very costly in terms of bits. Is > there some other way of dealing with this problem? Couldn't MyHDL just issue > a warning? > > You can not have multiple drivers if you wish to have a physical realization of the circuit. The circuits are always driving their outputs, in the physical circuit -without including tri-states, mux, etc- there isn't the notion of not driving an output. Depending on the type of source and sinks in the technology you could implement "wire and" and "wire or" but I am unaware of any tools (synthesis, par) that will support multiple drivers. If you wish to have a physical realization of your circuit description you will need to define how the outputs are arbitrated. This could be as simple as "or"ing the outputs together but it depends on your circuit. Simulation allows multiple drivers so you can easily do things in testbenches, portions of the HDL that are not intended to be synthesized. This is is the same in Verilog and VHDL. Multiple drivers are not part of the synthesizable subset. Even if MyHDL were to let this pass you would fail when you try and synthesize the underlying HDL. Hope that helps, Chris |
From: Christopher F. <chr...@gm...> - 2011-11-23 16:13:59
|
On 11/22/11 3:15 PM, Norbo wrote: > On Mon, 21 Nov 2011 17:28:05 +0100, Christopher Felton > <chr...@gm...> wrote: > >> On 11/21/2011 8:52 AM, Oscar Diaz wrote: >>> 2011/11/19 Norbo<Nor...@gm...>: >>>> I have played a bit with myhdl and created the following: >>>> >>>> ---------------------------------------------------------- >>>> from myhdl import * >>>> >>>> def bin2gray(A,B, C, width): >>>> >>>> """ Gray encoder. >>>> >>>> B -- input intbv signal, binary encoded >>>> G -- output intbv signal, gray encoded >>>> width -- bit width >>>> >>>> """ >>>> @always_comb >>>> def logic(): >>>> C[0].next = A + B >>> >>> It seems that you have a bug here. Why you assign the result of a sum >>> to a single bit? that's the reason why the converter tried to use >>> "to_std_logic" for the output. If you want a normal sum, it should be >>> >>> C.next = A + B >>> >>> and the VHDL converter will put synthesizable code: >>> >>> C<= (A + B); >>> >> >> Good eye Oscar! >> >> Yes, there are a couple issues with the bin2gray that was provided (I >> assumed the bin2gray was an example for conversion means and not an >> actual bin2gray?). I didn't notice at first glance but if you want to >> assign a single bit of a bit-vector you need to do: >> >> C.next[0] = A + B >> >> >> If you assign the bit correctly the conversion works (even though it >> functional doesn't work). Simulation will not work!. Not sure why the >> converter didn't flag this? Possible error detection enhancement. >> >> Also using the "+" operator instead of the bitwise "^" will cause >> problems in simulation. The "+" will overflow the range for a single >> bit. >> >> My previous reply can be ignored and should be ignored. If any changes >> need to be made they would be in the error catching/reporting and not >> modifications to the conversion. >> >> Regards, >> Chris >> >>> Or, if you want a binary to gray encoder, just use the example from >>> the documentation >>> >>> http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design >>> >>> >>> Best Regards >>> > > Well the thing is: > > If i write: > > C[4:0].next = A+B in vhdl it gets -> C(4-1 downto 0)<= resize(A + > B,4); > > or: > > C[1:0].next = A+B in vhdl it gets -> C(1-1 downto 0)<= resize(A + B,1); > which in in my understanding this makes kind of sense because the result > is cropped to the output size. (maybe a warning would be nice, but it > could be difficult if the calculation gets longer) > > > but when i write : > > C[0].next = A+B > (which is actually the same as the above C[1:0].next = A+B) > in vhdl it gets -> C(0)<= to_std_logic(A + B); > and is not synthesisable. > > As mentioned, the above is the incorrect syntax. The converted results are unreliable. To do bit indexing you need to do: C.next[0] = A[0] + B[1] If you do C[0].next that is used for a list of signals. If you run a simulation (testbench) this error will be identified. Review the following links: http://www.myhdl.org/doc/current/manual/intro.html#bit-indexing http://www.myhdl.org/doc/current/manual/conversion_examples.html#a-small-combinatorial-design Also, run a simple simulation. That will give you some more insight into the issue. Regards, Chris |
From: garyr <ga...@fi...> - 2011-11-23 00:30:02
|
Code that appears to be OK when simulated produces errors "Signal has multiple drivers" when I attempt to convert it to Verilog. In my case the two drivers never access the signal at the same time so there should be no problem. Google didn't turn up any useful information. In one case a rather simple change eliminated the problem. Another occurrence I eliminated by adding a multiplexer that routed a start and an 8-bit command signal to the shared module. A third occurrence involves an unsigned division module having 32-bit parameters dividend, divisor and quotient. The dividend and divisor signals would have multiple drivers. Using a multiplexer approach here would be very costly in terms of bits. Is there some other way of dealing with this problem? Couldn't MyHDL just issue a warning? |