差别
这里会显示出您选择的修订版和当前版本之间的差别。
|
for [2018/09/14 10:18] group001 创建 |
for [2018/09/14 10:57] (当前版本) group001 |
||
|---|---|---|---|
| 行 9: | 行 9: | ||
| - while:循环中的判断条件可以很简单,也可以很复杂。 | - while:循环中的判断条件可以很简单,也可以很复杂。 | ||
| - foe:常用于固定次数或可变次数的循环,要定义一个循环变量。 | - foe:常用于固定次数或可变次数的循环,要定义一个循环变量。 | ||
| - | 例子:\\ | + | 使用for循环可以减少代码的书写量,使得代码更加紧凑,不易出错,而且可以做到随意配置。\\ |
| + | 例子:ISN是一个parameter,是在实例化时从顶层传递过来的,其值不是固定值。最好的办法是用for循环,否则一条一条地书写,根本就不好维护。\\ | ||
| <code verilog> | <code verilog> | ||
| - | //forever example | + | reg [ISN-1:0] SelY; |
| - | initial begin | + | reg [ISN*2-1:0] TransY; |
| - | clk <= 0; | + | reg [ISN*3-1:0] BurstY; |
| - | forever #(PERIOD/2.0) clk = ~clk; | + | reg [ISN-1:0] WriteY; |
| + | always @(*) | ||
| + | begin | ||
| + | for (i = 0; i < ISN; i = i + 1) | ||
| + | begin | ||
| + | SelY[i*1 +: 1] = (SelX[i*1 +: 1] & {1{os_access_bits[i]}}); | ||
| + | TransY[i*2 +: 2] = (TransX[i*2 +: 2] & {2{os_access_bits[i]}}); | ||
| + | BurstY[i*3 +: 3] = (BurstX[i*3 +: 3] & {3{os_access_bits[i]}}); | ||
| + | WriteY[i*1 +: 1] = (WriteX[i*1 +: 1] & {1{os_access_bits[i]}}); | ||
| + | end | ||
| end | end | ||
| - | |||
| - | //repeat example | ||
| - | repeat (3) @(posedge clk); | ||
| - | |||
| - | //while example | ||
| - | begin: count1s | ||
| - | reg [7:0] tempreg; | ||
| - | count = 0; | ||
| - | tempreg = rega; | ||
| - | while (tempreg) begin | ||
| - | if (tempreg[0]) | ||
| - | count = count + 1; | ||
| - | tempreg = tempreg >> 1; | ||
| - | end | ||
| - | end | ||
| - | |||
| </code> | </code> | ||
| + | 例子:使用for循环实现优先级解码器。这里NUMBER怎么变化都没关系,代码也不需要像用casez一样需要修改。\\ | ||
| + | <code verilog> | ||
| + | parameter NUMBER = 8; | ||
| + | localparam WIDTH=$clog2(NUMBER); | ||
| + | reg [NUMBER-1:0] intc_src; | ||
| + | reg [WIDTH:0] intc_number; | ||
| + | reg flag; | ||
| + | always @(*) | ||
| + | begin | ||
| + | intc_number = (1'b1 << WIDTH); | ||
| + | flag = 1; | ||
| + | for (i = 0; flag && (i < NUMBER); i = i + 1) | ||
| + | begin: intc_number_block | ||
| + | if (intc_src[i] == 1) begin | ||
| + | intc_number = i; | ||
| + | flag = 0; | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | </code> | ||
| + | 现在的综合工具很强大,当循环个数是常量的时候,这样书写的for循环是可以综合的,例如上面的两个for循环。但是如果循环个数是变量的时候,那么任何综合工具都综合不出来,这是因为硬件规模必须是有限的、固定的。当综合工具遇到循环语句时,就把它们展开成若干条顺序执行的语句,然后再综合成电路。若循环个数是常数,则展开的语句数是确定的,所以可以综合;而若循环个数是变量,则展开的语句数是不确定的,对应的硬件电路数量也不能确定,所以无法综合。 | ||