TCJJ

导航

SV_2_verilog基础

1. verilog 的一般设计流程:

1. specification(specs)

2. high level design

3. low level (micro) design

4. RTL coding

5. verification

2. 以一个arbiter为例

Specs

  • Two agent arbiter;
  • Active hogh asynchronous reset;
  • Fixed priority,with agent 0 have priority over agent 1;
  • Grant will be asserted as long as request is asserted.

Block diagram of aribiter

 

 从模块图中我们可以清楚的看出端口的数量以及数据的流向,甚至对于一些简单的设计我们也能根据模块图画出真值表,卡诺图进一步简化电路设计,但是对于一些大型的设计就会变得复杂,需要更有利的工具来帮助设计。

Design

 

 对于一个简单的仲裁器来说,可以画出如上的状态图。圆圈代表着状态,箭头代表着数据的流向。状态机可以明确的之处设计的所有逻辑。

RTL Coding(partly)

module arbiter (
// Two slashes make a comment line.
clock      , // clock
reset      , // Active high, syn reset
req_0      , // Request 0
req_1      , // Request 1
gnt_0      , // Grant 0
gnt_1        // Grant 1
);
//-------------Input Ports-----------------------------
// Note : all commands are semicolon-delimited
input           clock               ;
input           reset               ;
input           req_0               ;
input           req_1               ;
//-------------Output Ports----------------------------
output        gnt_0                 ;
output        gnt_1                 ;
//arbiter block
always @ (posedge clock)
    if (reset) begin
        gnt_0 <= 0;
        gnt_1 <= 0;
    end else if (req_0)  begin
        gnt_1 <= 0;
        gnt_0 <= 1;
    end  else if (gnt_1) begin
        gnt_0 <= 0;
        gnt_1 <= 1;
    end
   else begin
        gnt_0 <= gnt_0;
        gnt_1 <= gnt_1;
    end

 

endmodule

3. 数据类型:

  • wire : 只能用于输出;

  • reg: 储存数据,可用于输入与输出;

  • ...

4. 操作符


Operator Type

Operator Symbol

Operation Performed

 Arithematic

*

Multiply

  /

Division

  +

Add

  -

Subtract

  %

Modulus

  +

Unary plus

  -

Unary minus

Logical

!

Logical negation

  &&

Logical and

  ||

Logical or

Relational

>

Greater than

  <

Less than

  >=

Greater than or equal

  <=

Less than or equal

Equality

==

Equality

  !=

inequality

Reduction

~

Bitwise negation

  ~&

nand

  |

or

  ~|

nor

  ^

xor

  ^~

xnor

  ~^

xnor

Shift

>>

Right shift

  <<

Left shift

Concatenation

{}

Concatenation

Conditional

?

conditional

 

5. 控制语句(control statement)

if - else

// begin and end act like curly braces in C/C++.
if (enable == 1'b1) begin
    data = 10; // Decimal assigned
    address = 16'hDEAD; // Hexadecimal
    wr_enable = 1'b1; // Binary  
end else begin
    data = 32'b0;
    wr_enable = 1'b0;
    address = address + 1;  
end

 没有else语句也可以,但容易导致锁存,电路综合时出现latch

case

case(address)
    0 : $display ("It is 11:40PM");
    1 : $display ("I am feeling sleepy");
    2 : $display  ("Let me skip this tutorial");
    default : $display  ("Need to complete");
endcase

 

如同if - else 一样,如果case语句不能覆盖所有情况且没有default语句,电路综合时也可能出现不想要的锁存,latch。

while

while (free_time) begin
    $display ("Continue with webpage development");
end

 Verilog中用的最多的一种结构:

 1 module counter (clk,rst,enable,count);
 2 input clk, rst, enable;
 3 output [3:0] count;
 4 reg [3:0] count;
 5                       
 6 always @ (posedge clk or posedge rst)
 7     if (rst) begin
 8       count <= 0;
 9     end else begin : COUNT
10       while (enable) begin
11         count <= count + 1;
12         disable COUNT;
13       end
14     end
15 
16 endmodule

For loop

1      for (i = 0; i < 16; i = i +1) begin
2             $display ("Current value of i is %d", i);
3       end

 

在verilog中不可使用++,--的操作符,只可使用i = i + 1。

Repeat

不同于for循环制定一个变量,使其自动递增想要的结果,repeat是显示指定一个循环数,以达到想要的结果。

1 repeat (16) begin
2   $display ("Current value of i is %d", i);
3   i = i + 1;
4 end
 

6. 变量赋值(Variable Assignment)

  • 组合逻辑元素只能用assign 和 always 逻辑块赋值;
  • 时序逻辑元素只能用always 逻辑块赋值;
  • initial逻辑块只能同于testbench。

initial

1 initial begin
2             clk = 0;
3             reset = 0;
4             req_0 = 0;
5             req_1 = 0;
6 end

Initial 块只在仿真开始执行一次。

always

always块与initial块不同的是,always在敏感列表满足时总是执行,块内不能驱动wire类型,只能驱动reg和integer类型。

1 always  @ (a or b or sel)//电平敏感
2 begin
3   y = 0;
4   if (sel == 0) begin
5     y = a;
6   end else begin
7     y = b;
8   end
9 end

  电平敏感常被综合为组合逻辑电路,赋值方式为阻塞赋值“=”。

1 always  @ (posedge clk )//边沿敏感
2 if (reset == 0) begin
3   y <= 0;
4 end else if (sel == 0) begin
5   y <= a;
6 end else begin
7   y <= b;
8 end

  边沿敏感常被综合为时序逻辑电路,赋值方式为非阻塞赋值“<=”。

1 //无敏感列表,下面的例子用于生成时钟,(#5表示延时5个时间单位)
2 always  begin
3   #5 clk = ~clk;
4 end

 

Assign statement

只对组合逻辑建模,并且会连续执行,所以assign语句又称为“连续赋值语句”。

1 assign out = (enable) ? data : 1'bz;
1 assign out = data;

7. 任务和函数(Task and  Function)

 函数和任务用来定义一一些需要反复运行的动作。

语法相同;不同点在于:

  •   task:可以有延迟;可用于时序电路和组合电路;
  •   function:不可以有延迟,只能用于组合电路。

7. Test Benches

 tesebench是用来测试所设计的模块是否符合前期规范的要求。

一个典型的用来测试仲裁器的testbench

 1 module arbiter (
 2 clock, 
 3 reset, 
 4 req_0,
 5 req_1, 
 6 gnt_0,
 7 gnt_1
 8 );
 9 
10 input clock, reset, req_0, req_1;
11 output gnt_0, gnt_1;
12 
13 reg gnt_0, gnt_1;
14 
15 always @ (posedge clock or posedge reset)
16 if (reset) begin
17  gnt_0 <= 0;
18  gnt_1 <= 0;
19 end else if (req_0) begin
20   gnt_0 <= 1;
21   gnt_1 <= 0;
22 end else if (req_1) begin
23   gnt_0 <= 0;
24   gnt_1 <= 1;
25 end
26 
27 endmodule
28 // Testbench Code Goes here
29 module arbiter_tb;
30 
31 reg clock, reset, req0,req1;
32 wire gnt0,gnt1;
33 
34 initial begin
35   $monitor ("req0=%b,req1=%b,gnt0=%b,gnt1=%b", req0,req1,gnt0,gnt1);
36   clock = 0;
37   reset = 0;
38   req0 = 0;
39   req1 = 0;
40   #5 reset = 1;
41   #15 reset = 0;
42   #10 req0 = 1;
43   #10 req0 = 0;
44   #10 req1 = 1;
45   #10 req1 = 0;
46   #10 {req0,req1} = 2'b11;
47   #10 {req0,req1} = 2'b00;
48   #10 $finish;
49 end
50 
51 always begin
52  #5 clock = !clock;
53 end
54 
55 arbiter U0 (
56 .clock (clock),
57 .reset (reset),
58 .req_0 (req0),
59 .req_1 (req1),
60 .gnt_0 (gnt0),
61 .gnt_1 (gnt1)
62 );
63 
64 endmodule
View Code

 

 1 //simulation result
 2  req0=0,req1=0,gnt0=x,gnt1=x
 3  req0=0,req1=0,gnt0=0,gnt1=0
 4  req0=1,req1=0,gnt0=0,gnt1=0
 5  req0=1,req1=0,gnt0=1,gnt1=0
 6  req0=0,req1=0,gnt0=1,gnt1=0
 7  req0=0,req1=1,gnt0=1,gnt1=0
 8  req0=0,req1=1,gnt0=0,gnt1=1
 9  req0=0,req1=0,gnt0=0,gnt1=1
10  req0=1,req1=1,gnt0=0,gnt1=1
11  req0=1,req1=1,gnt0=1,gnt1=0
12  req0=0,req1=0,gnt0=1,gnt1=0

 

注意:输出为wire或reg,输入为reg

 

posted on 2021-02-26 02:12  TCJJ  阅读(216)  评论(0)    收藏  举报

1