??? 04/20/07 18:25 Read: times |
#137665 - elsif Responding to: ???'s previous message |
Mahmood Elnasser said:
I just wrote this psudo random number generator which produces 16 bit random number once GENerate key is pressed. This simple program ate about 50% of my XC9572XL CPLD's resources. Well, you have 72 flops in that chip. your shift register used 16 of them (and in an FPGA, that'd be one slice using an SRL16) and the output register used another 16. That's 32, which is almost half of 72. Throw in the logic to do the XORs and the compare, and that's why we don't do shift registers in CPLDs ... Re: your first example not complaining about combinatorial latches: Of course you won't get those complaints as you've written a synchronous process. The synchronous storage element properly handles this case (see below). As for your second example failing: shift_reg gets assigned in two different (by that I mean: unrelated) "if" blocks. The first is the reset clause, and the second is the clock edge. The error message ("bad synchronous description") tells you exactly what's wrong ... the synthesizer can't figure out which template your code matches, so it barfs. Note that your second example: a) will simulate; however, the simulation won't be what you expect, as the effect of the if (RSTn = '0') clause will get overwritten by the if (rising_edge(FCLK)) clause. b) would have been accepted by older/other synthesis tools, which would essentially thrown away the reset (perhaps with a warning, perhaps not) and then you'd be hosed. Finally, a point about synchronous vs combinatorial processes: with the former, you don't need to write an "else" clause (unless your design requires it). For example, flop : process (clk) is begin if (rising_edge(clk)) then q <= d; end if; end process flop;doesn't need an "else q <= q;" statement because a "real" flip-flop would never need it since the flip flop doesn't care about anything other than the rising edge of the clock. This is still true in the case of an enabled flop: en_flop : process (clk) is begin if (rising_edge(clk)) then if (ce = '1') then q <= d; end if; // ce end if; // clock end process en_flop;In this case, when ce = '0', the storage element never "sees" the clock edge due to "clock gating" (which is not what happens in the flop!) so the previous value is retained. (What really happens inside the flop is that there's a "recirculating mux" in front of the flop's data input, which is selected by ce: if ce is '1' then the flop data input is driven by d; if ce is '0', then the mux selects the flop's q output, which then drives the flop data input.) In a combinatorial process, to avoid inferring a combinatorial latch, you MUST ensure that all "else" cases are covered, otherwise the tools must figure out some clever way of retaining the previous value (because nothing new was assigned). Brand X will properly choose a latch element from the library. Consider: latch : process (le, d) is begin if (le = '1') then q <= d; end if; // le end process latch;So you have to ask yourself: "what's the value of q if le is false?" Well, we "know" that it retains its previous value, so how does it do that? -a |