原创
[博客大赛]关于verilog和数字电路的关系(二)
7、动态移位寄存器
assign DO = data[SEL]; always @(posedge CLK) begin if (CE == 1 ’b1) data < = {data[DATAWIDTH - 2 : 0 ], SI}; end
动态移位寄存器与移位寄存器相比,则是在描述好了移位寄存器后,通过描述连线,将需要的某位寄存器值连接至输出来实现。 verilog 是在画一幅电路图,所以这些语句块之间的顺序不会影响电路的结构。
8、选择器
always @(sel or di) begin case (sel) 3 ’b000 : do = di[ 7 ]; 3 ’b001 : do = di[ 6 ]; 3 ’b010 : do = di[ 5 ]; 3 ’b011 : do = di[ 4 ]; 3 ’b100 : do = di[ 3 ]; 3 ’b101 : do = di[ 2 ]; 3 ’b110 : do = di[ 1 ]; default : do = di[ 0 ]; endcase end
或者
always @(sel or di) begin if (sel == 3 ’b000) do = di[ 7 ]; else if (sel == 3 ’b001) do = di[ 6 ]; else if (sel == 3 ’b010) do = di[ 5 ]; else if (sel == 3 ’b011) do = di[ 4 ]; else if (sel == 3 ’b100) do = di[ 3 ]; else if (sel == 3 ’b101) do = di[ 2 ]; else if (sel == 3 ’b110) do = di[ 1 ]; else do = di[ 0 ]; end
在C语言里,if、case都是控制程序的分支走向,在 verilog 里,就是一个选择器了。上面利用if和case描述了一个8-1的选择器。
9、存储器
reg [NB_COL * COL_WIDTH - 1 : 0 ] RAM [SIZE - 1 : 0 ]; always @(posedge clk) begin do < = RAM[addr]; end generate genvar i; for (i = 0 ; i < NB_COL; i = i + 1 ) begin always @(posedge clk) begin if (we) RAM[addr][(i + 1 ) * COL_WIDTH - 1 : i * COL_WIDTH] < = di[(i + 1 ) * COL_WIDTH - 1 : i * COL_WIDTH]; end end endgenerate
通过REG的数组可以描述一个存储器,在C中for是一个循环结构,而在 verilog 中,代表着将for中的描述的电路单元进行复制。
有了上述的基本电路单元模块的描述,我们便可以根据想要生成的电路结构,利用原件描述加上连线描述来描绘出我们需要的并且能让软件看懂的电路结构了。在电路的描述过程中, verilog 中使用的关键词和语法并不多,总结下来便是:
always+clk+"<="在连线之间插入寄存器。
always+"<="则在连线中插入锁存器。
if、case在元件中插入选择器,assign在元件之间插入连线。
操作符则在连线中间插入逻辑函数和运算单元。
利用这些操作便可以描述一个电路结构了。当然,为了让我们描述的电路方便管理移植等,可以利用parameter、generate等这些关键词来让电路的描述更加方便、管理和移植。
用户439848 2013-8-21 19:12
用户447620 2013-8-12 16:34