IC验证必备的Verilog知识(二):设计方法

目录

1. 组合电路的设计

1.1. 三人表决器

1.2. 加法器

1.3. 数据选择器

1.4. 编码器

 1.5. 奇偶校验器

2. 时序逻辑电路的设计

2.1. 一个FSM的写法

2.2. D触发器的写法

2.3. 一个十进制计数器的写法

 2.5. 序列信号发生器

 2.6. 有限同步状态机


1. 组合电路的设计

1.1. 三人表决器

用真值表设计思想的话,应该用case语句罗列各种情况,case({a,b,c}) 3'b011:out=1;这样只要有俩个1以上就out输出为1,否则为0。如果是抽象描述方式(我称为数学设计思想)。可以令sum=a+b+c,然后判断sum是否大于2。逻辑代数形式也可以考虑,令out=(a&b)|(b&c)|(a&c);。这是常用的三种设计思想,门级设计不考虑,过于具象化。

1.2. 加法器

设计加法器,最简单也是最高效的应该是抽象描述方式(数学设计思想),令{cout, sum} = a+b+cin。

超前进位加法器视情况看是否掌握(看各大公司笔试题,考到几率不大)。

1.3. 数据选择器

数据选择器通常采用case语句实现,罗列真值表

1.4. 编码器

同样可以用case语句实现,下面是一个8-3编码器的verilog描述。

 我们可以发现只要输入和输出是一一对应的,这里的编码器,包括译码器,数据选择器等等都可以通过case语句实现。(注意加上default,避免综合成锁存器)

但如果是有限编码器呢?输入输出不是一一对应,比如8-3优先编码器。输入8'b10000000和8'b11000000等等只要高位对应是1,那么都输出对应最高位的信号。这种情况下可以使用casex来实现。

 1.5. 奇偶校验器

奇偶校验器的实现就是判断(比如一个8bit数)数的1的个数,按照好理解的数学设计思想,可以这样做,将所有bit位加起来,看看是奇数还是偶数。可以通过按位与再加上取模运算来实现。也可以通过直接按位异或来实现(按位异或是两位相异则输出为1,相同输出为0)。

2. 时序逻辑电路的设计

时序逻辑电路分析的方法包括逻辑表达式,状态转移图。因此可以通过状态转移图去写,就是有限状态机(FSM)的写法。

2.1. 一个FSM的写法

module hyf(clk, in, out);
	input clk;
	input in;
	output out;
	reg out;
	parameter s0=2'b00, s1=2'b01, s2=2'b11, s3=2'b10;
  	reg [1:0]state,next_state;
  	reg clk;
  always@(*) 
	case(state)
		s0:
          if(in) 	begin next_state <= s1 ;  out<=0;end
     	  else 	begin next_state <= s0  ; out<=0;end
		s1:
          if(in) begin next_state <= s2  ; out<=0;end
    	  else 	begin next_state <= s3  ; out<=0;end
		s2:
          if(in) begin	next_state <= s2  ; out<=1;end
      	  else begin	next_state <= s3 ;  out<=0;end
		s3:
          if(in) begin	next_state <= s1  ; out<=0;end
      else begin	next_state <= s0  ; out<=0;end
	endcase
  always@(posedge clk)
    state<=next_state;
endmodule 

module tb;
  reg clk1,in1,out1;  
  hyf dut(clk1,in1,out1);
  initial begin
    clk1 <=0;
    forever begin
      #5 clk1 <= !clk1;
    end
  end   
initial begin
  #100 $finish();
end
endmodule

当然也可以用数学设计思维来写。每输入一位,就将之前整体的bit位左移。可以按照下面这种思路写

2.2. D触发器的写法

一个简单的异步复位的D触发器

module d_trigger(d,q,clk,rst);
    input d,rst,clk;
    output q;
    reg q;
    
    always@(posedge clk or negedge rst)
    if(!rst) q <= 0;
    else     q <= d;
endmodule

2.3. 一个十进制计数器的写法

主体部分就是写出在时钟上升沿判定,是否复位,是否达到进位值,是的话置0,否则+1。

module counter(clk, rst, out);
	input clk,rst;
   	output out;
    reg [3:0]out;
  
  always@(posedge clk)
    if(!rst) out <= 4'b0000;
  else if(out == 4'b1001) out<= 4'b0000;
  else out <=out+1;

endmodule

2.4. 环形移位寄存器

环形移位寄存器是在每一拍将所有位向前挪动一位,最高位挪到最低位。有傻瓜式写法(在每一拍 out[1] <= out[0]; out[2] <= out[1],... ),也有按照数学设计思想的,通过拼接操作完成。

 2.5. 序列信号发生器

以下题为例,简单的想法是产生一个6'b100111的数,随后从大到小发送各个bit位的数。这是数不动,发送动的思想,但这样实现起来有点麻烦。通过移位寄存器,使得数移动,然后只发送最高bit位即可。

 2.6. 有限同步状态机

有限同步状态机常用描述方法如下:

第一个进程always语句:描述状态机在每一拍状态的跳转;

第二个进程always语句:描述状态机在跳转的时候,根据每个状态跳转到不同的次态。 

猜你喜欢

转载自blog.csdn.net/weixin_55225128/article/details/127082363