参考:verilog数字系统设计教程【第四版】夏宇闻

repeat语句用阻塞赋值语句,与用非阻塞语句产生的结果差别非常大,所以将二者放在同一篇文章中。

1、赋值语句 2、repeat 语句介绍   2.1、用法要点   2.2、代码举例    代码1:always 语句实现 repeat n 次赋值    代码2:initial 语句实现 repeat n 次赋值    代码3:给 memory 类型数据赋值    代码4:实现 memory 类型储值

1、赋值语句

在 verilog HDL 语言中,信号有两种赋值方式,两者的区别见下表:

非阻塞赋值方式   (non_blocking)  b<=a阻塞赋值方式  (blocking)  b=a在语句块中,上面语句所赋值的变量值不能立即为下面语句所用。b的值在赋值语句执行完后立刻改变块结束后才能完成这次赋值操作,而所赋值的变量值是上一次赋值得到的。赋值语句执行完毕后,块才结束在编写可综合的时序逻辑模块时,这是最常用的赋值方法。在时序逻辑中使用时,可能会产生意想不到的结果

仿真代码如下:

`timescale 1ns / 1ps

module tb_assignment;

reg clk;

reg rst;

initial begin

clk = 1;

rst = 1;

#99;

rst = 0;

end

always #1 clk = ~clk;

reg [7:0] count;

reg [7:0] count_r1;

reg [7:0] count_r2;

reg [7:0] non_count;

reg [7:0] non_count_r1;

reg [7:0] non_count_r2;

always @(posedge clk)begin

if(rst )begin

non_count <= 8'd0;

non_count_r1 <= 8'd0;

non_count_r2 <= 8'd0;

end else begin

non_count <= non_count + 1'd1;

non_count_r1 <= non_count;

non_count_r2 <= non_count_r1;

end

end

always @(posedge clk)begin

if(rst )begin

count = 8'd0;

count_r1 = 8'd0;

count_r2 = 8'd0;

end else begin

count = count + 1'd1;

count_r1 = count;

count_r2 = count_r1;

end

end

endmodule

仿真结果图

2、repeat 语句介绍

连续执行一条语句N次。

repeat语句格式

1、单语句

repeat(表达式)语句

2、多语句

repeat(表达式)begin

多条语句;

end

2.1、用法要点

表达式通常为常量表达式。

2.2、代码举例

代码1:always语句实现 repeat n 次赋值

实现乘法器

reg i_Clk;

reg i_rst;

initial begin

i_Clk = 1;

i_rst = 1;

#101;

i_rst = 0;

end

initial begin

forever #1 i_Clk = ~i_Clk;

end

reg [3:0] size = 4;

reg [3:0] data_a = 4'b0110;

reg [3:0] data_b = 4'b1100;

//===============================================================================

// always 语句

//===============================================================================

//============================================================= =

reg [7:0] result = 0;

reg [7:0] shift_a;

reg [7:0] shift_b;

always@(posedge i_Clk)begin

if(i_rst)begin

result = 8'd0;

shift_a = data_a;

shift_b = data_b;

end else

repeat(size) begin

if(shift_b[0])

result = result + shift_a;

shift_a = shift_a << 1;

shift_b = shift_b >> 1;

end

end

//============================================================= <=

reg [7:0] non_result = 0;

reg [7:0] non_shift_a;

reg [7:0] non_shift_b;

always@(posedge i_Clk)begin

if(i_rst)begin

non_result <= 8'd0;

non_shift_a <= data_a;

non_shift_b <= data_b;

end else

repeat(size) begin

if(non_shift_b [0])

non_result <= non_result + non_shift_a;

non_shift_a <= non_shift_a << 1;

non_shift_b <= non_shift_b >> 1;

end

end

仿真结果如下:

代码2:inital 语句实现 repeat n 次赋值

实现乘法器

//===============================================================================

// initial 只执行一次 同上个版本共用 i_Clk 等信号

//===============================================================================

//================================================ =

initial begin

result = 8'd0;

shift_a = data_a;

shift_b = data_b;

#10;

repeat(size) @(posedge i_Clk) begin

if(shift_b[0])

result = result + shift_a;

shift_a = shift_a << 1;

shift_b = shift_b >> 1;

end

end

//================================================ <=

initial begin

non_result <= 8'd0;

non_shift_a <= data_a;

non_shift_b <= data_b;

#10;

repeat(size) @(posedge i_Clk) begin

if(non_shift_b[0])

non_result <= non_result + non_shift_a;

non_shift_a <= non_shift_a << 1;

non_shift_b <= non_shift_b >> 1;

end

end

仿真结果如下: 因为 @(posedge i_Clk) 即实现下一时钟的作用,所以此处 <= 和 = 的仿真结果一样。

代码3:用于给 memory 类型数据赋值

reg i_Clk;

reg i_rst;

initial begin

i_Clk = 1;

i_rst = 1;

#20;

i_rst = 0;

end

initial begin

forever #1 i_Clk = ~i_Clk;

end

//==============================================

// assgn memory

//==============================================

reg [3:0] test_data = 0;

reg [3:0] i = 0;

reg [3:0] buffer[7:0];

reg [3:0] j = 0;

reg [3:0] non_buffer[7:0];

always @ (posedge i_Clk)begin

if(i_rst)

test_data <= 4'd0;

else

test_data <= test_data + 1'd1;

end

//================================================================= =

always @(posedge i_Clk) begin

i = 0 ;

if (i_rst) // repeat 8 times to assign initial value

repeat (8) begin

buffer[i] = 4'b0 ;

i = i + 1 ;

end

else

repeat (5) begin

buffer[i] = test_data ;

i = i + 1 ;

end

end

/* 错误写法

always @(posedge i_Clk) begin

i = 0 ;

if (i_rst)

repeat (8) //i在下一时钟上升沿即变为8

i = i + 1 ;

else

repeat (5) //i在下一时钟上升沿即变为5

i = i + 1 ;

end

always @(posedge i_Clk) begin

i = 0 ;

if (i_rst)

repeat (8) //在下一时钟上升沿buffer[8]变为0,其他buffer[]未赋初值

buffer[i] = 4'b0 ;

else

repeat (5) //在下一时钟上升沿buffer[5]变为test_data,其他buffer[]未赋值

buffer[i] = test_data;

end

*/

//================================================================= <=

always @(posedge i_Clk) begin

j <= 0 ;

if (i_rst)

repeat (8) begin

non_buffer[j] <= 4'b0; //此处 = 和 <= 结果都无影响

j <= j + 1 ;

end

else

repeat (5) begin

non_buffer[j] <= test_data; //此处 = 和 <= 结果都无影响

j <= j + 1 ;

end

end

/* 将 j 和 buffer 分开

always @(posedge i_Clk) begin

j <= 0 ;

if (i_rst)

repeat (8)

j <= j + 1 ;

else

repeat (5)

j <= j + 1 ;

end

always @(posedge i_Clk) begin

if (i_rst)

repeat (8)

non_buffer[j] <= 4'b0 ;//此处 = 和 <= 结果都无影响

else

repeat (5)

non_buffer[j] <= test_data ; //此处 = 和 <= 结果都无影响

end

*/

代码4:实现 memory 类型储值

reg i_Clk;

reg i_rst;

initial begin

i_Clk = 1;

i_rst = 1;

#30;

i_rst = 0;

end

initial begin

forever #4 i_Clk = ~i_Clk;

end

reg data_valid;

reg [3:0] data_demo;

reg [3:0] buffer_cnt;

reg [3:0] buffer_demo [7:0];

always @ (posedge i_Clk)begin

if(i_rst) begin

data_valid <= 1'd0;

data_demo <= 4'd0;

end else begin

if (data_demo == 4'd15)

data_demo <= data_demo;

else

data_demo <= data_demo + 1'd1;

if (data_demo == 4'd8)

data_valid <= 1'd0;

else if(data_demo == 4'd0)

data_valid <= 1'd1;

end

end

always@(posedge i_Clk)begin

if(i_rst)

buffer_cnt <= 4'd0;

else if(data_valid)

if(buffer_cnt == 4'd7)

buffer_cnt <= buffer_cnt;

else

buffer_cnt <= buffer_cnt + 1'd1;

else

buffer_cnt <= 4'd0;

end

always @(posedge i_Clk) begin

j = 0 ;

if (i_rst)

repeat (8) begin

buffer_demo[j] <= 4'b0;

j = j + 1 ;

end

else if(data_valid)

buffer_demo[buffer_cnt] <= data_demo;

end

仿真结果图:

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: