热度 3
2015-5-18 10:40
863 次阅读|
0 个评论
转载至fpga4fun,觉得对重新理解fpga很好,而且从来没有在中文网站上看到这种东西,而且讲的通俗易懂,以后多看点英文网站。先转下来备忘,从以前的一个自己的博客上转载过来的。。 (1)Binary counters The simplest of counters A fast and efficient binary counter can be built using a couple of Verilog lines. For example, here's a 32bit counter. reg cnt; always @(posedge clk) cnt = cnt+1; Such counter counts from 0 to 4294967295, and then rolls-back 0 to continue its course. It takes little resources and runs fast in an FPGA thanks to an hidden carry-chain (more on that later). For now, let's see a few variations. First it's a good idea to explicitly give a starting value, even if it's 0. reg cnt = 0; always @(posedge clk) cnt = cnt+1; Note that if we don't specify a starting value, simulation tools will refuse to work, and some synthesis tools might also change the starting value on their own... so it's really a good idea to always specify a starting value. We could also have used an asynchronous reset to specify a starting value, but the simplest way is shown above. Now if you need more features, here's an example of a 10bit counter (counts up to 1023) that starts counting from 300, and has enable and direction controls. reg cnt = 10'd300; // 10bit counter, starts at 300 wire cnt_enable; // 0 to disable the counter, 1 to enable it wire cnt_direction; // 0 to counter backward, 1 to count forward always @(posedge clk) if(cnt_enable) cnt = cnt_direction ? cnt+1 : cnt-1; Note that FPGA flip-flops always start at 0, so the FPGA synthesis tool have to play some tricks to make non-zero values work, but it's transparent (the synthesis tool puts some well-placed inverters in the logic). Counter tick Let's say we need a "tick" signal that is asserted once every 1024 clock. Most likely we would create a 10bit counter and some logic to generate the "tick". Let's see how to do that. First we make our 10bit counter. It counts from 0 to 1023 and then rolls-back. reg cnt = 0; always @(posedge clk) cnt = cnt+1; Now we could decide that our "tick" is asserted when the counter reaches its maximum value. wire tick = (cnt==1023); An alternate way to write that is wire tick = cnt; // assert "tick" when all the cnt bits are 1 The drawback of these tick signals is that they create a big chunk of logic (a 10bit AND gate here). Not that big a deal for only 10bit but if our counter is 32bit or bigger, that would be a waste. The alternate way is to rely on the (usually hidden) carry chain that the FPGA is using behind the scene. We just need a bit of arm twisting to convince the FPGA to provide the info he is hiding... reg cnt = 0; // 32bit counter wire cnt_next = cnt+1; // next value with 33bit (one bit more than the counter) always @(posedge clk) cnt = cnt_next ; wire tick = cnt_next ; // gets the last bit of the carry chain (asserted when the counter reaches its maximum value) Try it, you'll see it works the same but takes less space in the FPGA (note: at the time of this writing, we tried both ISE and Quartus-II and both do a good job with 0 as the start value. But Quartus-II gets confused for non-zero starting values and makes a big blob of logic) . (2)Special counters Modulus counters A modulus counter is a binary counter that rolls back before its natural end value. For example, let's say you want a modulus 10 counter (counts up to 9), you can write this. reg cnt = 0; // we need 4 bits to be able to reach 9 always @(posedge clk) if(cnt==9) cnt = 0; else cnt = cnt+1; or this (a little more compact) reg cnt = 0; always @(posedge clk) cnt = (cnt==9) ? 0 : cnt+1; Now a little of (free) optimization is available if you realize that we don't actually need to compare all the 4 bits of the counter to 9. The code below uses only bit 0 and bit 3 in the comparison. always @(posedge clk) cnt = ((cnt 9)==9) ? 0 : cnt+1; Gray counters A gray counter is a binary counter where only one bit7changes at a time. Yes, that's possible, see below the output of a 4bit Gray counter. 0000 0001 0011 0010 0110 0111 0101 0100 1100 1101 1111 1110 1010 1011 1001 1000 Gray code is mostly used to send values across clock domains (this way it has an uncertainty of only 1). The easiest way to create a Gray counter is to first make a binary counter, and then convert the value to Gray. module GrayCounter( input clk, output reg cnt_gray = 0); reg cnt; always @(posedge clk) cnt = cnt+1; // 4bit binary counter assign cnt_gray = cnt ^ cnt ; // then convert to grayendmodule It is also possible to create a native Gray counter. wire cnt_cc = {cnt_cc ~cnt_gray , ^cnt_gray, 1'b1}; // carry-chain type logic always @(posedge clk) cnt_gray = cnt_gray ^ cnt_cc ^ cnt_cc ; (3)LFSR counters Let's say you want a counter that counts more or less "randomly", you can use an LFSR. Here's an example. As you can see, an LFSR is a shift-register with some XOR gates. The one shown above is an 8-taps LFSR (it uses 8 flip-flops). The output sequence is as follow (assuming all the flip-flops start at 1): 0000 0001 0011 0010 0110 0111 0101 0100 1100 1101 1111 1110 1010 1011 1001 1000 Here's the LFSR source code. module LFSR8_11D( input clk, output reg LFSR = 255 // put here the initial value);wire feedback = LFSR ; always @(posedge clk)begin LFSR = feedback; LFSR = LFSR ; LFSR = LFSR ^ feedback; LFSR = LFSR ^ feedback; LFSR = LFSR ^ feedback; LFSR = LFSR ; LFSR = LFSR ; LFSR = LFSR ; end endmodule Notice that we made it start at 255. That's because 0 is a dead-end state . So we can choose any start value but 0. After that, the LFSR changes value at each clock cycle but never reaches 0, so it goes through only 255 values (out of 256 possible combinations of the 8bit output bus) before starting again. Now, instead of taking the 8bit output, we could have used only one of the flip-flops to feed a 1bit output. This way we get a string of 255 '0' and '1' that looks random (although it repeats itself after 255 clocks). Useful for a noise generator...