Site Home Archive Home FAQ Home How to search the Archive How to Navigate the Archive
Compare FPGA features and resources
Threads starting:
Authors:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
On 3/1/2013 4:35 PM, GaborSzakacs wrote: > rickman wrote: >> On 2/25/2013 9:05 AM, GaborSzakacs wrote: >>> muzaffer.kal@gmail.com wrote: >>>> On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote: >>>>> always @(negedge nrst or posedge PCLK or negedge begin) >>>>> ... >>>>> So,how can i determine what event does really happen in begin end >>>>> block?? >>>> >>>> First of all begin is a reserved verilog keyword so "negedge begin" is >>>> going to give you heartache; change the identifier. >>>> >>>> Secondly if you want to synthesize this, you have to check if your >>>> target library supports two asynchronous inputs simultaneously. Some >>>> (asic) libraries have async set & reset flops so, it might synthesize >>>> if you write "if (!nrst) foo <= 0; if (!brst) foo <= 1;" etc. But to >>>> get the right behavior, you have to follow the (set/reset) priority of >>>> your library flop to get the simulation behavior to match it. >>>> >>>> Lastly if you are just trying to get it to simulate it, you can write >>>> some complicated case/if-else statements to check the state of every >>>> variable to see which event has actually fired but you should realize >>>> that there is no way this will be synthesis friendly. >>> >>> The point I was making is that even with if/else logic, >>> you can't always tell which event triggered the process, >>> because there may be more than one signal which is in >>> the state it would be if it had just triggered the process. >>> >>> You might be able to detect the event if you also kept track >>> of the previous state of each variable, but the process >>> won't do this for you, so you would need more registers >>> for this. >> >> This is different from VHDL. The signal keeps track of the current >> state, the prior state and whether or not the state changed for this >> delta cycle. rising_edge(foo) checks that foo is in the '1' state (or >> 'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is >> it '1', again, I don't recall). These conditions can all be checked in >> the code using IF statements. >> >> >>> For simulation, it is more typical to use multiple processes >>> to describe a flop with multiple asynchronous controls. Also >>> note that to describe for example a D FF with async set and reset, >>> you really need to be sensitive to both edges of the set and >>> reset inputs to handle the case where both were asserted at the >>> same time and then one of them released. I don't know of >>> any synthesizers that allow you to infer this sort of flop, >>> so I've always instantiated them if necessary. >> >> I don't follow what you mean. I'm not as familiar with Verilog. In >> VHDL you would just include both the set and reset signal in the >> sensitivity list which runs the process anytime any of those signals >> change state. Then in the logic the states are checked to describe >> what the logic should do about it. Sometimes that will be nothing, for >> example on the falling edge of the rising edge sensitive clock signal. >> The process will be activated by the falling edge, but the code will >> not execute any assignments. >> >> A D FF with both set and reset async inputs is not hard to describe in >> VHDL. I can't imagine this is hard to describe in Verilog either. I >> don't understand what you mean by "I don't know of any synthesizers >> that allow you to infer this sort of flop". Is that really a >> limitation in Verilog? >> >> process(Clk, Reset, Set) begin >> if (Reset) then >> Q <= '0'; >> elsif (Set) then >> Q <= '1'; >> elsif (rising_edge(Clk)) then >> Q <= Dinput; >> end if; >> end process; >> >> In this case the Reset input has priority over the Set which has >> priority over the Clk. How do you do this in Verilog? I just realized >> that I need to download a Verilog cheat sheet. I have a couple for >> VHDL, but none for Verilog... my bad! >> >> Wouldn't you just write... >> >> always@(posedge Clk or Reset or Set) >> if (Reset)... >> > The problem in Verilog is that you can't place the edge dependancy > in the if statements within the always block. A clocked block in > Verilog has the edge dependencies in the sensitivity list itself > and you use the if statement to check the current (post event) state > of the signals. So you don't really have the equivalent of the VHDL > code where the if statements for the set/reset are level triggered > but the if statement for the clock is edge triggered. There was a > prolonged discussion of this in comp.lang.verilog where the bottom > line was that you need two processes to properly describe a D-FF > with two asynchronous controls. > > Regarding your suggestion, the block would trigger on either > edge of set or reset, and only on the rising edge of clk. Now > if you wrote: > > always @ (posedge clk or reset or set) > if (reset) > Q <= 0; > else if (set) Q <= 1; > else Q <= D; > > Then the problem is that the final else cannot really check that you > got here because of the rising clock edge. You could add: > > else if (clk) Q <= D; Yes, I get it. If the process was triggered by a falling edge of reset or set the code would do the same thing as a rising edge of clk. > But even that would not work in the case where you released the > last asynchronous input while the clock was already high. And > since you don't get to this point until after the event that > triggered the block, you can't say else @ (posedge clk) Q <= D; > because that would say to wait for another rising edge. > > Bottom line, for Verilog to model this properly you need two processes: > > always @ (set or reset) > if (reset) Q = 0; > else if (set) Q = 1; > > always @ (posedge clk) > Q <= D; > > Which works fine for simulation, but gives you a "multisource" error > for synthesis. Yes, indeed. Thanks for the info. -- RickArticle: 154951
On 3/1/2013 4:39 PM, GaborSzakacs wrote: > rickman wrote: >> On 2/25/2013 2:18 PM, glen herrmannsfeldt wrote: >>> yu zhou<zydgyy@gmail.com> wrote: >>>> always @(negedge nrst or posedge PCLK or negedge begin) >>>> begin >>>> ... >>>> end >>> >>>> So,how can i determine what event does really happen in begin >>>> end block?? >>> >>> If you can't figure it out, how would the synthesis tool or >>> actual FF figure it out? >>> >>> In a more usual case, you see something like: >>> >>> always @(posedge clk or posedge reset) begin >>> if(reset) q<= 0; >>> else q<=d; >>> end >>> >>> (I might have that wrong, but maybe you see the idea.) >>> >>> If reset goes high, it resets. >>> >>> If reset is high on a clock positive edge, it stays reset. >>> >>> If reset is not high on a clock positive edge, it clocks data in. >>> >>> There are four cases here to consider. clk high or low on >>> posedge reset, and reset high or low on posedge clk. >>> >>> (The tools usually don't know that there is the case that >>> both change at once. In actual logic, it would usually be >>> a setup/hold violation and/or race condition.) >>> >>> If you have three edge events, then you have to consider the >>> state of the other two signals on any of the three events, >>> for 12 combinations. >>> >>> Note the use of posedge reset, though the FF reset is not edge >>> triggered. The only interesting thing happens on the posedge. >>> The rest of the state has to depend on the current values of the >>> other signals on the transition. (If reset is high, it stays reset >>> even when a clk event occurs.) >> >> Yes, that is the part I'm not clear on. What if the simulation starts >> with reset at '1'. Is an event generated on reset anyway so that the >> process runs and q is reset? >> > The simulation always starts with everything undriven. So initial > statements at time zero, or initial values in a reg declaration > will always create an edge. Thus I typically start my simulation > with: > > initial begin > reset = 1; > clk = 0; > . . . > #100 reset = 0; > . . . > end > > And all of my asynchronous reset processes trigger at time zero. Note > that a clock is typically initialized to zero which would trigger any > negedge processes at time zero as well. I have a fuzzy recollection that in VHDL they either changed or are discussing changing rising_edge so that it only triggers on a logic edge rather than triggering from a non-logic state like 'U' or 'X' or I assume even 'Z'. Maybe I'm only hallucinating, but I think I read this. In any event, I'm pretty sure that initialization happens prior to the start of the simulation so that it can't cause edges, but I'm not certain. I think I would have a clear recollection if it could because I would have been doing that... -- RickArticle: 154952
rickman <gnuarm@gmail.com> wrote: > On 2/25/2013 9:05 AM, GaborSzakacs wrote: >> muzaffer.kal@gmail.com wrote: >>> On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote: >>>> always @(negedge nrst or posedge PCLK or negedge begin) >>>> So,how can i determine what event does really happen in begin end >>>> block?? (snip) >> The point I was making is that even with if/else logic, >> you can't always tell which event triggered the process, >> because there may be more than one signal which is in >> the state it would be if it had just triggered the process. But are there any useful cases where that is true? Now, you can write plenty of things that don't make any sense in actual logic. >> You might be able to detect the event if you also kept track >> of the previous state of each variable, but the process >> won't do this for you, so you would need more registers >> for this. > This is different from VHDL. The signal keeps track of the current > state, the prior state and whether or not the state changed for this > delta cycle. rising_edge(foo) checks that foo is in the '1' state (or > 'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is > it '1', again, I don't recall). These conditions can all be checked in > the code using IF statements. OK, now consider: always @(posedge clk or posedge reset) begin if(reset) q<=0; else q<=d; end There are two cases where the block is executed, when either clk or reset goes high. If (asynchronous) reset is high, then q goes to zero, even if the block was entered by clk. >> For simulation, it is more typical to use multiple processes >> to describe a flop with multiple asynchronous controls. Also >> note that to describe for example a D FF with async set and reset, >> you really need to be sensitive to both edges of the set and >> reset inputs to handle the case where both were asserted at the >> same time and then one of them released. I don't know of >> any synthesizers that allow you to infer this sort of flop, >> so I've always instantiated them if necessary. > > I don't follow what you mean. I'm not as familiar with Verilog. In > VHDL you would just include both the set and reset signal in the > sensitivity list which runs the process anytime any of those signals > change state. Then in the logic the states are checked to describe what > the logic should do about it. Sometimes that will be nothing, for > example on the falling edge of the rising edge sensitive clock signal. > The process will be activated by the falling edge, but the code will not > execute any assignments. In verilog, you might do something, but it might be the same thing that was done before. > A D FF with both set and reset async inputs is not hard to describe in > VHDL. I can't imagine this is hard to describe in Verilog either. I > don't understand what you mean by "I don't know of any synthesizers that > allow you to infer this sort of flop". Is that really a limitation in > Verilog? > process(Clk, Reset, Set) begin > if (Reset) then > Q <= '0'; > elsif (Set) then > Q <= '1'; > elsif (rising_edge(Clk)) then > Q <= Dinput; > end if; > end process; > In this case the Reset input has priority over the Set which has > priority over the Clk. How do you do this in Verilog? I just realized > that I need to download a Verilog cheat sheet. I have a couple for > VHDL, but none for Verilog... my bad! > Wouldn't you just write... > always@(posedge Clk or Reset or Set) > if (Reset)... I believe that would be more like a transparent latch. Note that it will also be executed on the falling edge of reset, and that reset will be 0 at that time. always @(posedge clk or posedge reset) begin if(reset) q<=0; else q<=d; end I suppose it is funny, as it looks like reset is edge triggered, but it only actually happens on the rising edge. If you do: always @(posedge clk) begin if(reset) q<=0; else q<=d; end then you should get a synchronous (clocked) reset. Now, if you wrote: always @(clk) begin q<=d; end you would get a FF clocked on both edges, which is rare. (Maybe they use them in DDR logic, but still rare.) -- glenArticle: 154953
GaborSzakacs <gabor@alacron.com> wrote: (snip, someone wrote) >> Yes, that is the part I'm not clear on. What if the simulation starts >> with reset at '1'. Is an event generated on reset anyway so that the >> process runs and q is reset? > The simulation always starts with everything undriven. So initial > statements at time zero, or initial values in a reg declaration > will always create an edge. Thus I typically start my simulation > with: > initial begin > reset = 1; > clk = 0; > . . . > #100 reset = 0; > . . . > end > And all of my asynchronous reset processes trigger at time zero. Note > that a clock is typically initialized to zero which would trigger any > negedge processes at time zero as well. You could do that, but most real logic requires some clock cycles to get into the appropriate state. I know that many microprocessors require reset to be active for some number, maybe 50, clock cycles. Now, for FPGAs the device usually does a global reset as it comes out of configuration, and you might want to simulate that. Then again, it might be that FPGA simulation doesn't do initial. -- glenArticle: 154954
Hi all, I'm using XST 14.2 and trying to use block RAMs to store constant data (i.e. as ROMs) for program code that will be run by a CPU. I want to infer the block RAMs during synthesis and then actually put data into them from an ELF during bitgen (in concert with a BMM file), so the data will be part of the bitstream and the FPGA will configure with the RAMs preloaded. Here’s the problem: XST keeps noticing that the great big arrays have nothing in them, and declares that “Signal <PMem_0> is used but never assigned. This sourceless signal will be automatically connected to value GND.”. Then it turns it into a LUT RAM for some reason, but only a tiny one. I’ve gone through the Spartan 6 XST user guide and the Xilinx constraint guide. I’ve tried attaching the KEEP attribute (set to “yes”), the S attribute (set to “yes”), and the EQUIVALENT_REGISTER_REMOVAL attribute (set to “no”) to the PMem signal. I’ve tried attaching all three of them at the same time. I’ve even tried simultaneously attaching all those attributes to both the memory block, the address lines going into it, the clock line, and the data lines coming out of it. Nothing helps! XST insists that the RAM is useless and destroys it. Surely this is a pretty common use case? What am I missing here? Thanks! ChrisArticle: 154955
On Sun, 03 Mar 2013 03:20:24 -0800, Christopher Head wrote: > Hi all, > I'm using XST 14.2 and trying to use block RAMs to store constant data > (i.e. as ROMs) for program code that will be run by a CPU. I want to > infer the block RAMs during synthesis and then actually put data into > them from an ELF during bitgen (in concert with a BMM file), so the data > will be part of the bitstream and the FPGA will configure with the RAMs > preloaded. > > Here’s the problem: XST keeps noticing that the great big arrays have > nothing in them, and declares that “Signal <PMem_0> is used but never > assigned. If you can't find a better answer, preload them with a function returning something other than 0. - BrianArticle: 154956
I have been looking for an SDIO serial port. A single chip would work as well. SDIO <-> async serial port Txd, Rxd, CTS, RTS Also Linux and Win drivers. Are these still around ?Article: 154957
(Sorry, this is a bit off topic, but I do use this to load bitfiles into FPGAs.) I have a Xeltek Superpro/Z eprom programmer, with their winsp ver. 1.0 software, running on Win 2K/Pro. Today I had need to erase and reprogram an Atmel 17LV256 EEPROM, but the erase button on the programmer GUI is grayed out. I can't remember if I ever did this before. I used to use UV-erasable EPROMS, but this one is electrically erasable. Is there a setting or option that enables erasing? (I know if I try to contact Xeltek, they will try to sell me a new programmer.) Thanks in advance for any hints! JonArticle: 154958
On Sun, 3 Mar 2013 12:51:29 +0000 (UTC) Brian Drummond <brian@shapes.demon.co.uk> wrote: > On Sun, 03 Mar 2013 03:20:24 -0800, Christopher Head wrote: > > > Hi all, > > I'm using XST 14.2 and trying to use block RAMs to store constant > > data (i.e. as ROMs) for program code that will be run by a CPU. I > > want to infer the block RAMs during synthesis and then actually put > > data into them from an ELF during bitgen (in concert with a BMM > > file), so the data will be part of the bitstream and the FPGA will > > configure with the RAMs preloaded. > > > > Here’s the problem: XST keeps noticing that the great big arrays > > have nothing in them, and declares that “Signal <PMem_0> is used > > but never assigned. > > If you can't find a better answer, preload them with a function > returning something other than 0. > > - Brian That sounds like a pretty awful answer, but it works. There seems to be a second basic rule as well, though: don't try to make your RAM one bit wide. I tried to make one-bit-wide RAMs and they just refused to infer BRAMs no matter what I did. Changing the RAM to be at least two bits wide made everything work just fine, despite the Xilinx docs claiming that BRAMs can, in fact, be 18,432 by 1 bit aspect ratio. I also recommend a function that returns lots of arbitrary values (personally I used a linear congruential random number generator). Sometimes XST notices that two RAMs have the same data in them and will combine them, so a function that just returns a simple pattern might not be sufficient. Got my situation sorted out, though, so thanks! ChrisArticle: 154959
On 3/3/2013 4:20 AM, Christopher Head wrote: > Hi all, > I'm using XST 14.2 and trying to use block RAMs to store constant data > (i.e. as ROMs) for program code that will be run by a CPU. I want to > infer the block RAMs during synthesis and then actually put data into > them from an ELF during bitgen (in concert with a BMM file), so the dat= a > will be part of the bitstream and the FPGA will configure with the RAMs= > preloaded. > > Here=E2=80=99s the problem: XST keeps noticing that the great big array= s have > nothing in them, and declares that =E2=80=9CSignal <PMem_0> is used but= never > assigned. This sourceless signal will be automatically connected to > value GND.=E2=80=9D. Then it turns it into a LUT RAM for some reason, b= ut only > a tiny one. > > I=E2=80=99ve gone through the Spartan 6 XST user guide and the Xilinx > constraint guide. I=E2=80=99ve tried attaching the KEEP attribute (set = to > =E2=80=9Cyes=E2=80=9D), the S attribute (set to =E2=80=9Cyes=E2=80=9D),= and the > EQUIVALENT_REGISTER_REMOVAL attribute (set to =E2=80=9Cno=E2=80=9D) to = the PMem signal. > I=E2=80=99ve tried attaching all three of them at the same time. I=E2=80= =99ve even > tried simultaneously attaching all those attributes to both the memory > block, the address lines going into it, the clock line, and the data > lines coming out of it. Nothing helps! XST insists that the RAM is > useless and destroys it. > > Surely this is a pretty common use case? What am I missing here? > > Thanks! > Chris > There should be a SET_DONT_TOUCH pragma or keyword. I have used this to=20 force some delays to not be optimized out, but I am still using ISE 11.x = or so. ISE supports it and it is a standard in the ASIC synthesis world. = It has been a couple of years since I used it, so if you want more=20 detail, I will have to go look in the code. BobHArticle: 154960
You can put a $readmemh to initialise the memory. reg [data_width-1:0] memory[0:depth-1]; initial begin $readmemh("filename.hex", memory); end Should work with both XST & Synplify.Article: 154961
http://alturl.com/4dtfw Price went from 17 EUR to 25 EUR Haven't checked other ICs, I'm only interested in this one.Article: 154962
On Sun, 03 Mar 2013 18:08:14 -0800, Christopher Head wrote: > On Sun, 3 Mar 2013 12:51:29 +0000 (UTC) > Brian Drummond <brian@shapes.demon.co.uk> wrote: > >> On Sun, 03 Mar 2013 03:20:24 -0800, Christopher Head wrote: >> > Here’s the problem: XST keeps noticing that the great big arrays have >> > nothing in them, and declares that “Signal <PMem_0> is used but never >> > assigned. >> >> If you can't find a better answer, preload them with a function >> returning something other than 0. > That sounds like a pretty awful answer, but it works. There seems to be > a second basic rule as well, though: don't try to make your RAM one bit > wide. I tried to make one-bit-wide RAMs and they just refused to infer > BRAMs no matter what I did. Interesting. THAT might be tool version dependent, I haven't heard that one before. > I also recommend a function that returns lots of arbitrary values > (personally I used a linear congruential random number generator). Agreed. That's the benefit of a function : easy to change the operation without touching the main design. An alternative function body would take a filename, and return the array filled with a default program (perhaps a bootloader?) ... didn't mention it yesterday because the thought of writing an ELF parser in VHDL was daunting ... but an Intel Hex reader in VHDL would be dead easy, and "objcopy -O" or other tools will get you from .elf to .hex. This would give you a ready-to-run bitstream, but still allow bitgen to update the software if desired. - BrianArticle: 154963
aleksazr@gmail.com wrote: > http://alturl.com/4dtfw > > Price went from 17 EUR to 25 EUR > > Haven't checked other ICs, I'm only interested in this one. Either price is much higher than the U.S. retail. DigiKey has stock at US $15.69 each. That's about 12 EUR. -- GaborArticle: 154964
On 3/1/2013 7:17 PM, glen herrmannsfeldt wrote: > rickman<gnuarm@gmail.com> wrote: >> On 2/25/2013 9:05 AM, GaborSzakacs wrote: >>> muzaffer.kal@gmail.com wrote: >>>> On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote: >>>>> always @(negedge nrst or posedge PCLK or negedge begin) > >>>>> So,how can i determine what event does really happen in begin end >>>>> block?? > > (snip) >>> The point I was making is that even with if/else logic, >>> you can't always tell which event triggered the process, >>> because there may be more than one signal which is in >>> the state it would be if it had just triggered the process. > > But are there any useful cases where that is true? > > Now, you can write plenty of things that don't make any sense > in actual logic. > >>> You might be able to detect the event if you also kept track >>> of the previous state of each variable, but the process >>> won't do this for you, so you would need more registers >>> for this. > >> This is different from VHDL. The signal keeps track of the current >> state, the prior state and whether or not the state changed for this >> delta cycle. rising_edge(foo) checks that foo is in the '1' state (or >> 'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is >> it '1', again, I don't recall). These conditions can all be checked in >> the code using IF statements. > > OK, now consider: > > always @(posedge clk or posedge reset) begin > if(reset) q<=0; > else q<=d; > end > > There are two cases where the block is executed, when either > clk or reset goes high. If (asynchronous) reset is high, > then q goes to zero, even if the block was entered by clk. The problem I was concerned about with this was the case where the simulation starts with reset at a '1' and the edge is not generated. But I am told this does not happen. In Verilog initializations create edges. I am fairly sure that I have initialized signals in VHDL simulations and they do *not* result in an edge at the start of the simulation. I am not certain because there is normally the reset preventing a clock from being recognized. > Now, if you wrote: > > always @(clk) begin > q<=d; > end > > you would get a FF clocked on both edges, which is rare. > (Maybe they use them in DDR logic, but still rare.) To the best of my knowledge there are *no* double edge FFs. DDR inputs have separate FFs which capture the input on the opposite edges of the clock, or they double the clock with a PLL and clock the data twice in each clock cycle on the rising edge of the doubled clock. -- RickArticle: 154965
On Mon, 04 Mar 2013 11:20:40 -0500, GaborSzakacs wrote: > aleksazr@gmail.com wrote: >> http://alturl.com/4dtfw >> >> Price went from 17 EUR to 25 EUR >> >> Haven't checked other ICs, I'm only interested in this one. > > Either price is much higher than the U.S. retail. DigiKey has stock at > US $15.69 each. That's about 12 EUR. > > -- Gabor Avnet has them for US $14.75 - 2600 in stock, min qty 1 -- Chisolm Republic of TexasArticle: 154966
Early (> 15 years ago) versions of Synplify would not infer memory from an SLV (which is an array of SL), but it would infer memory from an array of std_logic_vector(0 to 0), which is an array of single bit vectors. Maybe XST will work with that too. Synplify has long since fixed that bug. AndyArticle: 154967
rickman wrote: > On 3/1/2013 7:17 PM, glen herrmannsfeldt wrote: >> rickman<gnuarm@gmail.com> wrote: >>> On 2/25/2013 9:05 AM, GaborSzakacs wrote: >>>> muzaffer.kal@gmail.com wrote: >>>>> On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote: >>>>>> always @(negedge nrst or posedge PCLK or negedge begin) >> >>>>>> So,how can i determine what event does really happen in begin end >>>>>> block?? >> >> (snip) >>>> The point I was making is that even with if/else logic, >>>> you can't always tell which event triggered the process, >>>> because there may be more than one signal which is in >>>> the state it would be if it had just triggered the process. >> >> But are there any useful cases where that is true? >> >> Now, you can write plenty of things that don't make any sense >> in actual logic. >> >>>> You might be able to detect the event if you also kept track >>>> of the previous state of each variable, but the process >>>> won't do this for you, so you would need more registers >>>> for this. >> >>> This is different from VHDL. The signal keeps track of the current >>> state, the prior state and whether or not the state changed for this >>> delta cycle. rising_edge(foo) checks that foo is in the '1' state (or >>> 'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is >>> it '1', again, I don't recall). These conditions can all be checked in >>> the code using IF statements. >> >> OK, now consider: >> >> always @(posedge clk or posedge reset) begin >> if(reset) q<=0; >> else q<=d; >> end >> >> There are two cases where the block is executed, when either >> clk or reset goes high. If (asynchronous) reset is high, >> then q goes to zero, even if the block was entered by clk. > > The problem I was concerned about with this was the case where the > simulation starts with reset at a '1' and the edge is not generated. But > I am told this does not happen. In Verilog initializations create > edges. I am fairly sure that I have initialized signals in VHDL > simulations and they do *not* result in an edge at the start of the > simulation. I am not certain because there is normally the reset > preventing a clock from being recognized. > > >> Now, if you wrote: >> >> always @(clk) begin >> q<=d; >> end >> >> you would get a FF clocked on both edges, which is rare. >> (Maybe they use them in DDR logic, but still rare.) > > To the best of my knowledge there are *no* double edge FFs. DDR inputs > have separate FFs which capture the input on the opposite edges of the > clock, or they double the clock with a PLL and clock the data twice in > each clock cycle on the rising edge of the doubled clock. > Xilinx allows inference of "DualEdge" flip-flops for CoolRunner II series only. Their guide shows this template: always @ (negedge clock or posedge clock) . . . Or for VHDL process (clock) begin if (clock'event) then . . . It's not clear why Verilog uses both edges rather than just: always @ (clock) which would work for simulation, perhaps they need to tell the difference between a "clocked" vs combinatorial process, where the case of "always @ (clock)" would ignore the sensitivity list. -- GaborArticle: 154968
DDR input primitives usually use separate SDR registers with separate outpu= ts for the rising and falling edge clocked values, and sometimes the negati= ve edge clocked value is realigned with the rising edge of the clock. DDR output registers do exist and are inferrable by some tools (at least Sy= nplify). Synplify recommends inferring two SDR registers and a mux controll= ed by the clock level. Do not try this without ensuring that the synthesize= r will convert it to a DDR register primitive. The actual FPGA primitive implementation in the IOB is not clear; it could = be two SDRs with an output mux selected by the clock level (and careful att= ention to silicon path delays to avoid glitches), or it could be a Flanter = circuit. Both of these implementations can be driven to emulate either an S= DR or DDR output register. Finally, the synthesis standard 1076.6-2004 identifies the methods of descr= ibing a DDR register (two clocks or two edges of one clock). In the two-edg= e model, both edges are tested explicitly, so the above code would not work= . Finally, if your device does not support DDR registers, you can emulate one= yourself with a Flancter circuit. AndyArticle: 154969
jonesandy@comcast.net wrote: > DDR input primitives usually use separate SDR registers with separate outputs for the rising and falling edge clocked values, and sometimes the negative edge clocked value is realigned with the rising edge of the clock. > > DDR output registers do exist and are inferrable by some tools (at least Synplify). Synplify recommends inferring two SDR registers and a mux controlled by the clock level. Do not try this without ensuring that the synthesizer will convert it to a DDR register primitive. > > The actual FPGA primitive implementation in the IOB is not clear; it could be two SDRs with an output mux selected by the clock level (and careful attention to silicon path delays to avoid glitches), or it could be a Flanter circuit. Both of these implementations can be driven to emulate either an SDR or DDR output register. > > Finally, the synthesis standard 1076.6-2004 identifies the methods of describing a DDR register (two clocks or two edges of one clock). In the two-edge model, both edges are tested explicitly, so the above code would not work. > > Finally, if your device does not support DDR registers, you can emulate one yourself with a Flancter circuit. > > Andy The CoolRunner II series from Xilinx, which is the only family where I've seen support for dual edged flop inference, only use the dual edge as a clock doubler, not to build a true DDR flip-flop that has two D inputs. I've never seen a proper DDR flip-flop that you could infer from HDL. -- GaborArticle: 154970
On Tuesday, March 5, 2013 11:39:11 AM UTC-6, Gabor wrote: snip... I've never seen a proper DDR flip-flop that you could infer from HDL. -- Gabor What synthesis tool(s) have you used? Synplify supports HDL inference of DDR output registers for Virtex II and later devices, and for Spartan 3 and later devices. These DDR registers have two D inputs. AndyArticle: 154971
jonesandy@comcast.net wrote: > On Tuesday, March 5, 2013 11:39:11 AM UTC-6, Gabor wrote: > snip... > I've never seen a proper DDR flip-flop that you could infer from HDL. -- Gabor > > What synthesis tool(s) have you used? > > Synplify supports HDL inference of DDR output registers for Virtex II and later devices, and for Spartan 3 and later devices. These DDR registers have two D inputs. > > Andy > > > I use XST because I can't afford a real synthesis tool. So what does the code look like to infer a DDR register with D0 and D1, C0 and C1 inputs? I would think (at least for Verilog) it would need two processes. Or can you only infer the register if the two clocks are the complements of the same signal? -- GaborArticle: 154972
I'm afraid I tried that one. No luck. Chris On Mon, 4 Mar 2013 12:11:43 -0800 (PST) jonesandy@comcast.net wrote: > Early (> 15 years ago) versions of Synplify would not infer memory > from an SLV (which is an array of SL), but it would infer memory from > an array of std_logic_vector(0 to 0), which is an array of single bit > vectors. Maybe XST will work with that too. > > Synplify has long since fixed that bug. > > AndyArticle: 154973
On Mon, 4 Mar 2013 02:03:34 -0800 (PST) Jon <jon@beniston.com> wrote: > You can put a $readmemh to initialise the memory. > > reg [data_width-1:0] memory[0:depth-1]; > > initial > begin > $readmemh("filename.hex", memory); > end > > Should work with both XST & Synplify. I'm using VHDL, not Verilog. Anyway, yes, initializing the memory to something with useful data in it does seem to solve it. This approach here has the risk that if the hex file starts out small, the synthesizer will optimize out some of the RAMs that aren't used, and then you can't get them back later when the hex file grows except by resynthesizing. ChrisArticle: 154974
On Wednesday, March 6, 2013 5:52:48 AM UTC, Christopher Head wrote: > On Mon, 4 Mar 2013 02:03:34 -0800 (PST) > > Jon wrote: > > > You can put a $readmemh to initialise the memory. > > > > reg [data_width-1:0] memory[0:depth-1]; > > > > initial > > begin > > $readmemh("filename.hex", memory); > > end > > > > Should work with both XST & Synplify. > > I'm using VHDL, not Verilog. Sorry to hear. > Anyway, yes, initializing the memory to > something with useful data in it does seem to solve it. This approach > here has the risk that if the hex file starts out small, the > synthesizer will optimize out some of the RAMs that aren't used, and > then you can't get them back later when the hex file grows except by > resynthesizing. I'm not sure it does that, but you can always pad out the hex file. Are you using objcopy to convert an ELF to binary and then to hex? If so, use the --pad-to option. The advantage of including the initialisation in your RTL is that it means your model can be simulated as well. Cheers, Jon
Site Home Archive Home FAQ Home How to search the Archive How to Navigate the Archive
Compare FPGA features and resources
Threads starting:
Authors:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z