原创 Verilog HDL学习

2011-6-15 08:01 7249 10 10 分类: FPGA/CPLD
第1章 简介

1.Verilog HDL是在哪一年首次被IEEE标准化的?

      Verilog HDL是在1995年首次被IEEE标准化的。

2.Verilog HDL支持哪三种基本描述方式

Verilog HDL可采用三种不同方式或混合方式对设计建模。这些方式包括:行为描述方式—使用过程化结构建模;数据流方式—使用连续赋值语句方式建模;结构化方式—使用门和模块实例语句描述建模

3.可以使用Verilog HDL描述一个设计的时序吗?

 Verilog HDL可以清晰的建立时序模型,故可以使用Verilog HDL描述一个设计的时序。

4.语言中的什么特性能够用于描述参数化设计?

在行为级描述中, Verilog HDL不仅能够在RT L级上进行设计描述,而且能够在体系结

构级描述及其算法级行为上进行设计描述,而且能够使用门和模块实例化语句在结构级进行结构描述,这种特性可用于描述参数化设计。

5.能够使用Verilog HDL编写测试验证程序吗?

能,可以编写testbench来对编写的程序进行验证。

6.Verilog HDL是由哪个公司最先开发的?

Verilog HDL是由Gateway Design Automation公司最先开发的

7.Verilog HDL中的两类主要数据类型是什么?

线网数据类型和寄存器数据类型。线网类型表示构件间的物理连线,而寄存器类型表示抽象的数据存储元件。

8.UDP代表什么?

UDP代表用户定义原语

9.写出两个开关级基本门的名称。

pmos  nmos

10.写出两个基本逻辑门的名称。

and  or

第2章  HDL指南

1.  在数据流描述方式中使用什么语句描述一个设计?

设计的数据流行为使用连续赋值语句进行描述

2.  使用` t i m e s c a l e 编译器指令的目的是什么?举出一个实例。

使用编译指令将时间单位与物理时间相关联。

例如` timescale 1ns /100ps   此语句说明时延时间单位为1ns并且时间精度为100ps (时间精度是指所有的时延必须被限定在0.1ns内)

3.  在过程赋值语句中可以定义哪两种时延?请举例详细说明。

1)  语句间时延: 这是时延语句执行的时延。

例:S u m = (A ^ B) ^ C i n;

#4  T 1 = A & C i n;

              在第二条语句中的时延规定赋值延迟4个时间单位执行

2)  语句内时延: 这是右边表达式数值计算与左边表达式赋值间的时延。

例:S u m = #3  (A^ B) ^ C i n;

这个赋值中的时延意味着首先计算右边表达式的值, 等待3个时间单位,然后赋值给S u m。

4. 采用数据流描述方式描述图2 - 4中所示的1位全加器。

20110615080224001.jpg

module  FA_Seq(A, B, Cin, Sum, Cout) ;

input  A, B, Cin ;

output  Sum, Cout;

wire  T1, T2, T3,S1;

 

assign  T1 = A & Cin;

assign  T2 = B & Cin;

assign  T3 = A & B;

assign  S1=A^B;

assign  Sum=S1^Cin;

assign  Cout= (T 1| T 2) | T 3;

            endmodule

4.  initial语句与always 语句的关键区别是什么?

1) initial语句:此语句只执行一次。

2) always语句:此语句总是循环执行, 或者说此语句重复执行。

6. 写出产生图2 - 1 0所示波形的变量B u l l s E y e的初始化语句。

20110615080225002.jpg

`timescale  1ns / 1ns

module Test (BullsEye) ;

output BullsEye;

reg  BullsEye;

initial

begin

BullsEye = 0;

BullsEye=#2 1;

BullsEye=#1 0;

BullsEye=#9 1;

BullsEye=#10 0;

BullsEye=#2 1;

BullsEye=#3 0;

BullsEye=#5 1;

end

endmodule

7. 采用结构描述方式描写图2 - 2中所示的2 - 4译码器。

20110615080225003.jpg

module Decoder2x4(A, B, EN, Z) ;

input A,B,EN;

output [0:3] Z;

wire Abar, Bbar;

 

not

v0(Abar,A),

v1(Bbar,B);

 

nand

N0(Z[0],Abar,Bbar,EN),

N1(Z[1],Abar,B,EN),

N2(Z[2],A,Bbar,EN),

N3(Z[3],A,B,EN);

endmodule

8. 为2 . 3节中描述的模块Decode2X4编写一个测试验证程序。

module Tes;

reg TA,TB,TEN;

wire [0:3]TZ;

Decoder2x4 DT2x4(TA,TB,TEN,TZ);

 

initial

begin

    $monitor($time,"A=%b,B=%b,EN=%b,Z=%b",TA,TB,TEN,TZ);

end

 

initial

begin

    TA=0;TB=0;TEN=0;

    #5  TA=1;TB=1;

    #5  TEN=1;

    #5  TA=0;TB=0;

    #5  TA=0;TB=1;

    #5  TA=1;TB=0;

end

endmodule

 

9. 列出你在Verilog HDL模型中使用的两类赋值语句。

连续赋值语句assign,阻塞赋值语句=

1 0. 在顺序过程中何时需要定义标记?

顺序过程内有局部声明的变量时,初始化语句中的顺序过程必须标记。

11. 使用数据流描述方式编写图2 - 11所示的异或逻辑的Verilog HDL描述,并使用规定的时延。

20110615080225004.jpg

module XORL(A,B,Z);

input A,B;

output Z;

wire Abar,Bbar,Z1,Z2;

 

assign  #1 Bbar=~B;

assign  #1 Abar=~A;

assign  #5 Z1=A&Bbar;

assign  #5 Z2=B&Abar;

assign  #4 Z=Z1|Z2;

endmodule

12. 找出下面连续赋值语句的错误。assign Reset = #2 ^ WriteBus;

不符合连续赋值语句的语法,应该为:

assign  #2  Reset = ^ WriteBus;

第3章  Verilog 语言要素

1.下列标识符哪些合法,哪些非法?

COunT, 1_2 Many, \**1, Real?, \wait, Initial

答:COunT合法,1_2 Many非法,\**1,Real?非法,\wait合法,Initial合法

2. 系统任务和系统函数的第一个字符标识是什么?

答:$

3.举例说明文本替换编译指令?

答:` define指令用于文本替换,它很像C语言中的#define指令,如:

` define MAX_BUS_SIZE 32

. . .

reg [ `MAX_BUS_SIZE - 1:0 ] AddReg;

4.在Verilog HDL 中是否有布尔类型?

答:没有

5.下列表达式的位模式是什么?

7'o44 位八进制数, 'Bx0位二进制数, 5'bx110位二进制数, 'hA0位十六进制数, 10'd2位十进制数, 'hzF位十六进制数

6.赋值后存储在Qpr中的位模式是什么?

reg [1:8*2] Qpr;

. . .

Qpr = "ME" ;

答:变量需要8 * 2位

7.如果线网类型变量说明后未赋值,其缺省值为多少?

答:z

8.Verilog HDL 允许没有显示说明的线网类型。如果是这样,怎样决定线网类型?

答:在Verilog HDL 中,有可能不必声明某种线网类型。在这样的情况下,缺省线网类型为1位线网。

  可以使用` default_nettype编译器指令改变这一隐式线网说明方式。使用方法如下:` default_nettype net_kind

例如,带有下列编译器指令:

`default_nettype wand

任何未被说明的网缺省为1位线与网。

9.下面的说明错在哪里?

integer [0:3] Ripple;

答:应该是integer Ripple [0:3]

10.编写一个系统任务从数据文件“ memA . data” 中加载32×64字存储器。

答:reg[15:0] RomB[0:2047];

$readmemb ("memA.data",RomB);

11.写出在编译时覆盖参数值的两种方法。

答:以使用参数定义语句或通过在模块初始化语句中定义参数值。

第4章  表达式

1.说明参数GATE_DELAY,参数值为5。

parameter GATE_DELAY = 5

2.假定长度为64个字的存储器,每个字8位,编写Verilog代码,按逆序交换存储器的内容。即将第0个字与第63个字交换,第1个字与第62个字交换,以此类推。

reg [7:0] mem [63:0];

integer i = 0;

reg [7:0] temp;

while(i < 32)

begin

       temp = mem;

       mem = mem[63 - i];

       mem[63 - i] = temp;

       i = i + 1;

end

3.假定32位总线Address_Bus,编写一个表达式,计算从第11位到底20位的归约与非。

~& addressBus[20:11]

4.假定一条总线Control_Bus[15:0],编写赋值语句将总线分为两条总线:Abus[0:9]和Bbus[6:1]。

Abus = ControlBus[9:0];

Bbus = ControlBus[15:10];

5.编写一个表达式,执行算术移位,将Qparity中包含的8位有符号数算术移位。

{Qparity[7-i:0], Qparity[7:8-i]}//左移,i表示移的位数

{Qparity[i-1:0], Qparity[7: i]}//右移,i表示移的位数

6.使用条件操作符,编写赋值语句选择NextState的值。如果CurrentState的值为RESET,那么NextState的值为GO;如果CurrentState的值为GO,则NextState的值为BUSY;如果CurrentState的值为BUSY,则NextState的值为RESET。

NextState = (CurrentState == RESET) ? Go : (CurrentState == Go ? BUSY : RESET)

7.使用单一连续赋值语句为图2-2所示的2-4解码器电路的行为建模。【提示:使用移位操作符、条件操作符和连接操作符。】

assign Z = EN ? {~(A & B), ~(A & ~B), ~(~A & B), ~(~A & ~B)} : 4b'1111;

8.如何从标量变量A、B、C和D中产生总线BusQ[3:0]?如何从两条总线BusA[3:0]和BusY[20:15]形成新的总线BusR[10:1]?

BusQ[3:0] = {D, C, B, A}

BusR[10:1] = {BusY[20:15], BusA[3:0]}

第5章  门电平模型化

1. 用基本门描述图5 - 11显示的电路模型。编写一个测试验证程序用于测试电路的输出。

使用所有可能的输入值对电路进行测试。20110615080225005.gif

module compare(A,B,Q);

 

input  [3:0]  A;

input  [3:0]  B;

output Q;

xor (E0,A[0],B[0]),

        (E1,A[1],B[1]),

        (E2,A[2],B[2]),

        (E3,A[3],B[3]);

or  (Q,E0,E1,E2,E3);

 

endmodule

测试:

module comparetest;

parameter CLK_PERIOD=20;//20ns 50MHZ

reg [7:0] p;

reg [3:0] A;

reg [3:0] B;

reg clock;

reg [7:0] p1;

 

initial

      clock=0;

always #(CLK_PERIOD/2)clock=~clock;

initial

       p=8'b00000000;

       always @(posedge clock)

begin

              p1=p;

              p=p1+1;

              A[0]=p[0];

              A[1]=p[1];

              A[2]=p[2];

              A[3]=p[3];

              B[0]=p[4];

              B[1]=p[5];

              B[2]=p[6];

              B[3]=p[7];

 end 

  compare inst_compare( .A(A), .B(B));

endmodule

2. 使用基本门描述如图5 - 1 2所示的优先编码器电路模型。

当所有输入为0时,输出Valid为0,否则输出为1。并且为验证优先编码器的模型行为编写测

试验证程序。

20110615080225006.gif

module priority(Data,Encode,valid);

input  [3:0]  Data;

output [1:0]  Encode;

output valid;

not (Data2bar,Data[2]);

and (out1,Data2bar,Data[1]);

or (out2,Data[1],Data[0]),

      (Encode[0],Data[3],out1),

      (Encode[1],Data[3],Data[2]),

      (valid,Data[3],Data[2],out2);

endmodule

测试:

module priority_tb;

reg [3:0]  Data;

initial

begin

            #100 Data[3]=0;Data[2]=0;Data[1]=0;Data[0]=0;

            #100 Data[3]=1;Data[2]=0;Data[1]=0;Data[0]=0;

end

priority inst_priority( .Data(Data));

endmodule

第6章  用户定义的原语

1. 组合电路U D P与时序电路U D P如何区别?

在组合电路U D P中,表规定了不同的输入组合和相对应的输出值。没有指定的任意组合输出为x。    

在时序电路U D P中,使用1位寄存器描述内部状态。该寄存器的值是时序电路U D P的输出值。有时钟作为输入信号。

2. UDP可有一个或多个输出,是否正确?

不正确。U D P只能有一个输出和一个或多个输入。

3. 初始语句可用于初始化组合电路U D P吗?

       不可以。只有时序电路U D P的状态初始化可以使用带有一条过程赋值语句的初始化语句实现。

4. 为图5 - 1 2中显示的优先编码器电路编写U D P描述。        使用测试激励验证描述的模型。

)[HMWNR8V_IB]~Q6_23ZQ[W.jpg

//encode.v

primitive  encode0 (encode0,data3,data2,data1,data0);

output   encode0;

input  data3,data2,data1,data0;

table

//data[3] [2] [1] [0] encode[1] [0] valid

       0 0 0 0 : 0;

       0 0 0 1 : 0; 

       0 0 1 ? : 1;

       0 1 ? ? : 0;

       1 ? ? ? : 1;

endtable

endprimitive

 

primitive  encode1 (encode1,data3,data2,data1,data0);

output   encode1;

input  data3,data2,data1,data0;

table

//data[3] [2] [1] [0] encode[1] [0] valid

       0 0 0 0 : 0;

       0 0 0 1 : 0;

       0 0 1 ? : 0; 

       0 1 ? ? : 1; 

       1 ? ? ? : 1;

endtable

endprimitive

 

//encoder.v

module encoder(encode,data);

       output [1:0]  encode;

       input  [3:0]  data;

        

        encode0(encode[0],data[3],data[2],data[1],data[0]);

        encode1(encode[1],data[3],data[2],data[1],data[0]);

endmodule

 

//encoder_tb.v

module encoder_tb;

reg [3:0] data;

initial

begin

            #100 data[3]=0;data[2]=0;data[1]=0;data[0]=0;

            #100 data[3]=1;data[2]=0;data[1]=0;data[0]=0;

            #100 data[3]=0;data[2]=1;data[1]=0;data[0]=0;

            #100 data[3]=0;data[2]=0;data[1]=1;data[0]=0;

end

encoder inst_encoder(.data(data));

endmodule

5. 为T触发器编写U D P描述。在T触发器中,如果数据输入为0,则输出不变化。如果数据输入是1,那么输出在每个时钟沿翻转。假定触发时钟沿是时钟下跳沿,使用测试激励验证所描述的模型。

//Q 初始化有问题??

//T_Edge_FF.v

primitive T_Edge_FF (Q, Clk, Data) ;

output Q;

reg  Q;

input Data,Clk;

initial Q = 0;

table

// Clk Data Q (State) Q( n e x t )

(10)  0   : 0      : - ;

(10)  0   : 1      : - ;

(10)  1   : 0      : 1 ;

(10)  1   : 1      : 0;

 

(1x)  0   : 0      : - ;

(1x)  0   : 1      : - ;

(1x)  1   : 0      : 1 ;

(1x)  1   : 1      : 0;

// 忽略时钟上边沿:

(?1) ? : ? : - ;

// 忽略在稳定时钟上的数据变化:

? (??): ? : - ;

endtable

endprimitive

 

//T_FF.v

module T_FF(Q,Clk,Data);

       output Q;

       input Data, Clk;

        

        T_Edge_FF(Q,Clk,Data);

endmodule

 

// T_FF_tb.v

module T_FF_tb;

       parameter CLK_PERIOD = 100; // 100ns 10MHz

       reg Data,Clk;

       wire Q;

initial

          Clk = 0;

       always #(CLK_PERIOD/2) Clk = ~Clk;

initial

begin

        #200 Data = 0;

        #200 Data = 1;

        #200 Data = 0;

        #200 Data = 1;

        #200 Data = 0;

end

T_FF inst_T_FF(.Q(Q),.Data(Data),.Clk(Clk));

endmodule

 

6. 以U D P方式为上跳边沿触发的J K触发器建模。如果J和K两个输入均为0,则输出不变。如果J为0,K为1,则输出为0。如果J是1,K是0,则输出是1。如果J和K都是1,则输出翻转。使用测试激励验证描述的模型。

// JK_FF.v

module JK_FF (Q, Clk, J,K) ;

output Q;

input J,K,Clk;

       JK_Edge_FF(Q,Clk,J,K);

endmodule

 

primitive JK_Edge_FF(Q, Clk, J,K) ;

output Q;

reg Q;

input J,K, Clk;

initial Q = 0;

table

// Clk   J  K  Q (State) Q( n e x t )

(01)  0  0   : ?      : -;

(01)  0  1   : ?      : 0;

(01)  1  0   : ?      : 1;

(01)  1  1   : 1      : 0;

(01)  1  1   : 0      : 1;

 

(0x)  0  0   : 0      : -;

(0x)  0  1   : 0      : 0;

(0x)  1  0   : 1      : 1;

(0x)  1  1   : 0      : 0;

//(0x)  1  1   : 0      : 1;

 

// 忽略时钟负边沿:

(?0) ? ? : ? : - ;

// 忽略在稳定时钟上的数据变化:

//? ??: ? : - ;

endtable

endprimitive

 

// JK_FF_tb.v

module JK_FF_tb;

       parameter CLK_PERIOD = 100; // 100ns 10MHz

       reg J,K,Clk;

       wire Q;

initial

          Clk = 0;

       always #(CLK_PERIOD/2) Clk = ~Clk;

initial      

begin

            #5 J=1;K=0;

            #100 J=0;K=0;

            #100 J=1;K=0;

            #100 J=1;K=1;

end

JK_FF inst_JK_FF(.Q(Q),.Clk(Clk),.J(J),.K(K));

endmodule

第7章  数据流模型化

1.例说明截止时延在连续赋值语句中如何使用

截止时延就是由输入信号的任一状态(1、0或X)转换到高阻状态“Z”输出之间的延时时间。

例如

assign #(4,1,6)      dout = din;

“()”中的三个值,4代表上升延时,1代表下降延时,6为截止延时

20110615080225008.jpg

由图中可知

上升时延为4ns(5~9ns)

下降时延为1ns(15~16ns)

截止时延为6ns(18~24ns),即从din=1’bz开始到dout为1’bz的延时

2.当对同一目标有2个或多个赋值形式时,如何决定目标有效值 ?

只要在右端表达式的操作数上有事件 (事件为值的变化)发生时,表达式即被计算;如果结果值有变化,新结果就赋给左边的线网。如果右端在传输给左端之前变化,在这种情况下,应用最新的变化值。

3.写出图5 - 1 0所示的奇偶产生电路的数据流模型描述形式。只允许使用 2个赋值语句,并规定上升和下降时延。

20110615080225009.gif

module Parity_9_Bit(D,Even,Odd);

input  [0:8]         D;

output Even,Odd;

assign  #(20, 16) Even = ^D;

assign  #(2) Odd = ~Even;

endmodule

整个奇偶产生电路累计的上升时间延时是4组,下降时间延时也是四组,所以,上升时间延时=5*4=20,下降时间延时为4*4=16。

4.使用连续赋值语句,描述图5 - 1 2所示的优先编码器电路的行为。20110615080225010.gif

module Encoder(Data,Encode,Valid);

input  [3:0]         Data;

output [1:0]         Encode;

output               Valid;

 

assign Encode[0] = Data[3] | (~Data[2] & Data[1]);

assign Encode[1] = Data[3] | Data[2];

assign Valid = Data[3] | Data[2] | Data[1] | Data[0];

endmodule

5.假定:

Tri0 [4:0]  Qbus;

assign Qbus = Sbus;

assign Qbus = Pbus;

如果Pbus和Sbus均为高阻态z,Qbus上的值是什么?

答:5’d0。无驱动源驱动Qbus,因而为0。

第8章  行为建模

1.initial语句always语句,哪一种可重复执行?

initial 语句只执行一次。initial 语句在模拟开始时执行,即在0时刻开始执行。

与i n i t i a l语句相反, a l w a y s语句可重复执行。

2. 顺序语句块和并行语句块的区别是什么?举例说明。顺序语句块能否出现在并行语句块

中?

答:1) 顺序语句块(b e g i n . . . e n d):语句块中的语句按给定次序顺序执行。

顺序语句块中的语句按顺序方式执行。每条语句中的时延值与其前面的语句执行的模拟

时间相关。一旦顺序语句块执行结束,跟随顺序语句块过程的下一条语句继续执行。顺序语

句块的语法如下:

b e g i n

[ :b l o c k i d{d e c l a r a t i o n s} ]

p r o c e d u r a l s t a t e m e n t ( s )

e n d

例如:

/ /产生波形:

b e g i n

#2 S t r e a m = 1;

#5 S t r e a m = 0;

#3 S t r e a m = 1;

#4 S t r e a m = 0;

#2 S t r e a m = 1;

#5 S t r e a m = 0;

e n d

2) 并行语句块(f o r k . . . j o i n):语句块中的语句并行执行。

并行语句块带有定界符f o r k和j o i n(顺序语句块带有定界符b e g i n和e n d),并行语句块中的

各语句并行执行。并行语句块内的各条语句指定的时延值都与语句块开始执行的时间相关。并行语句块内的所有语句必须在控制转出语句块前完成执行。

并行语句块语法如下:

f o r k

[ :b l o c k i d{d e c l a r a t i o n s} ]

p r o c e d u r a l s t a t e m e n t(s) ;

j o i n

例如:

// 生成波形:

f o r k

#2 S t r e a m = 1;

#7 S t r e a m = 0;

#10 S t r e a m = 1;

#14 S t r e a m = 0;

#16 S t r e a m = 1;

#21 S t r e a m = 0;

j o i n

顺序语句块能可以出现在并行语句块中

3.语句块在什么时候需要标识符?

答:需要在语句块中声明寄存器变量时,需要标识符。带标识符的语句块可被引用;例如,语句块可使用禁止语句来禁止执行。此外,语句块标识符提供唯一标识寄存器的一种方式。但是,要注意所有的寄存器均是静态的,即它们的值在整个模拟运行中不变。

4.在always语句中是否有必要指定时延?

答:没有必要指定时延。在将Verilog程序进行综合的时候延时的内容不识别,如果需要可以testbench里指定延时。

5. 语句内部时延和语句间时延的区别是什么?举例说明。

1) 语句间时延: 这是时延语句执行的时延。
2) 语句内时延: 这是右边表达式数值计算与左边表达式赋值间的时延。

在赋值语句中表达式右端出现的时延是语句内部时延。通过语句内部时延表达式,右端

的值在赋给左端目标前被延迟。

语句间时延是右端表达式在语句内部时延之前计算,随后进入时延等待,再对左端目标赋值。

下例说明了语句间和语句内部时延的不同。

D o n e = #5 'b1; //语句内部时延控制

b e g i n

T e m p = 'b1;

#5 D o n e = T e m p; //语句间时延控制

e n d

相同。

6.阻塞性赋值和非阻塞性赋值有何区别?

阻塞性赋值使用“=”,非阻塞性赋值使用“<=”。

阻塞性赋值,在其后所有语句执行前执行,即在下一语句执行前该赋值语句完成执行;非阻塞性赋值执行时,计算右端表达式,右端值被赋于左端目标,并继续执行下一条语句,在当前时间步结束或任意输出被调度时,对左端目标赋值。

非阻塞性赋值对于左边赋值变量的更新操作的优先级要低于阻塞赋值,也低于非阻塞赋值本身等号右边的表达式计算,需要等到当前仿真周期结束时才能被执行。

7. casex语句与c a s e语句有何区别?

casex是case的派生语句,casex语句将分支条件中所有的x(未知)和z(高阻)值被认为是无关位。其他情况下casex与case完全相同。

8. 能否在a l w a y s语句中为线网类型(例如w i r e型线网)赋值?

不能 , 网线类型只能在过程块之外赋值。

9. 产生一个在5 ns时刻开始、周期为10 ns的时钟波形。

always

#5 C l k = ~ C l k;

/ /产生时钟周期为1 0的波形

10. 用一个i n i t i a l语句和1个f o r e v e r循环语句替代下述a l w a y s语句。

a l w a y s

@ (E x p e c t e d o r O b s e r v e d)

if (E x p e c t e d !== O b s e r v e d) b e g i n

$d i s p l a y ("MISMATCH: Expected = %b,Observed = %b"

Expected, Observed ) ;

$s t o p;

e n d

答:

i n i t i a l

b e g i n

f o r e v e r

if (E x p e c t e d !== O b s e r v e d)

begin

$d i s p l a y ("MISMATCH: Expected = %b,Observed = %b"

Expected, Observed ) ;

$s t o p;

end

e n d

11. 按如下条件,两个a l w a y s语句中N e x t S t a t e A和N e x t S t a t e B上的值是多少: C l o c k P在5 ns时有1个正沿;C u rre n t S t a t e在时钟边沿前值为5,并且在时钟沿3 ns后改变为7?

a l w a y s

@ (p o s e d g e C l o c k P)

#7 N e x t S t a t e A = C u r r e n t S t a t e;

a l w a y s

@ (p o s e d g e C l o c k P)

N e x t S t a t e = #7 C u r r e n t S t a t e;

答:N e x t S t a t e A在12ns之后为7

N e x t S t a t e B在12ns之后为5

12. 使用行为建模方式写出如下有限状态机模型的行为描述。

I n p ( G a k ) P r e s e n t S t a t e N e x t S t a t e O u t p u t ( Z u k )

0 NO_ONE NO_ONE 0

1 NO_ONE ONE_ONE 0

0 ONE_ONE ONE_ONE 0

1 ONE_ONE TWO_ONE 0

0 TWO_ONE NO_ONE 0

1 TWO_ONE THREE_ONE 1

0 THREE_ONE NO_ONE 0

1 THREE_ONE THREE_ONE1

答:m o d u l e  M e a l y  (G a k, Clock, Z u k) ;

i n p u t  G a k, Clock;

o u t p u t  Z u k;

r e g  Z u k;

p a r a m e t e r  NO_ONE = 0, ONE_ONE = 1, TWO_ONE = 2, THREE_ONE = 3;

r e g [1:2] P_State, N_State;

a l w a y s

@ (n e g e d g e C l o c k) //同步时序逻辑部分。

P_State = N_State;

a l w a y s

@ (P_State or G a k,) b e g i n: C O M B P A R T

c a s e (P_State)

NO_ONE:

i f (G a k)

b e g i n

Z = 0;

N_State = ONE_ONE;

e n d

else

b e g i n

Z = 0;

N_State = NO_ONE;

ONE_ONE:

i f (G a k)

begin

Z = 0;

N_State = TWO_ONE;

e n d

else

begin

Z = 0;

N_State = ONE_ONE;

e n d

TWO_ONE:

i f (G a k)

begin

Z = 1;

N_State = THREE_ONE;

e n d

else

begin

Z = 0;

N_State = NO_ONE;

e n d

THREE_ONE:

i f (G a k)

begin

Z = 1;

N_State = THREE_ONE;

e n d

else

begin

Z = 0;

N_State = NO_ONE;

e n d

e n d c a s e

e n d / /顺序块C O M B P A R T结束。

e n d m o d u l e

13. 使用a l w a y s语句描述J K触发器的行为功能。

m o d u l e  JK (J,K, Clock, Q,Q*) ;

i n p u t  J,K, Clock;

o u t p u t  Q,Q*;

i n i t i a l

Q=0;

a l w a y s

@ (n e g e d g e C l o c k) //同步时序逻辑部分。

 Q=Q*;

a l w a y s

@ (Q,J,K) b e g i n: C O M B P A R T

c a s e (Q)

0:

i f (J)

Q* = 1;

Else

Q* =0;

1:

i f (K)

Q* = 1;

Else

Q* =0;

e n d c a s e

e n d / /顺序块C O M B P A R T结束。

e n d m o d u l e

14. 描述如下电路行为:该电路在每一个时钟下跳沿(负沿)检查输入数据,当输入数据U s g为1 0 11时,输出A s m被置为1。

a l w a y s

@ (n e g e d g e C l o c k)  b e g i n

 i f (U s g= =4b’1011)

A s m = 1;

end

15. 描述多数逻辑电路行为。输入为1 2位的向量。如果其中1的数量超过0的数量,输出设置为1。当D a t a R e a d y为1时,才对输入数据进行检查。

input  [11:0]in,DataReady;

output out;

reg [11:0] tmp;

integer i;

integer count;

initial

count =0;

parameter poly=12’b100000000000;

always@( DataReady)

begin

if(DataReady)

begin

for(i=0;i<=11;i++)

begin

tmp=in& poly;

if(tmp!=12’b000000000000)

count++;

end

if(count>6)

out=1;

end

end

 

第9章 结构建模

1 .模块实例语句与门实例语句的区别是什么?

在带参数的模块引用中,参数的指定方式与门级实例语句中时延的定义方式相似;但由于对复杂模块的引用时,其实例语句不能像对门实例语句那样指定时延,故此处不会导致混淆。

2 .当端口悬空时,即端口没有被连接时,端口的值是什么?

模块的输入端悬空,值为高阻态 z。模块的输出端口悬空,表示该输出端口废弃不用。

3 .对于9 . 3节中的模块FA,O R _ D E L AY值为4,X O R _ D E L AY值为7,A N D _ D E L AY值为5,写出其结构描述形式。

m o d u l e  H A(A , B , S , C);

i n p u t  A , B;

o u t p u t  S, C;

p a r a m e t e r  A N D _ D E L A Y = 5, X O R _ D E L A Y = 7;

 

a s s i g n   #XOR _ D E L A Y  S=A^B;

a s s i g n   #A N D _ D E L A Y  C=A&B;

e n d m o d u l e

 

m o d u l e  F A(P, Q, Cin, Sum, Cout) ;

i n p u t  P, Q, Cin;

o u t p u t  Sum, Cout;

 p a r a m e t e r  O R _ D E L A Y = 4;

w i r e S1, C1, C2;

 

/ /两个模块实例语句

 HA  h1 (P, Q, S1, C1); //通过位置关联。

 HA  h2 ( .A(C i n), .S(S u m), .B(S 1), .C(C 2));  //通过端口与信号的名字关联。

 

 / /门实例语句:

Or  #O R _ D E L A Y  O1 (Cout, C1, C2) ;

e n d m o d u l e

4 .用本章讲述的模块FA编写执行加法和减法的 4位A L U的结构模型。

module ALU(A,B,Q, C,M);

input [3:0] A;

input [3:0] B;

input M;

output [3:0] Q;

ouput C;

reg [3:0] Q;

reg C;

wire C1,C2,C3;

 

initial

begin

if(M==0)//M=0做减法(A-B),M=1做加法

begin

B<=B^4’b1111;

B<=B+4’b0001;

end

end

 

FA FA1(.P(A[0]),.Q(B[0]),.Cin(0),.Sum(Q[0]),.Count(C1)),  

      FA2 P(A[1]),.Q(B[1]),.Cin(C1),.Sum(Q[1]),.Count(C2)),     

      FA3(P(A[2]),.Q(B[2]),.Cin(C2),.Sum(Q[2]),.Count(C3)),                                                                  

      FA4(.P(A[3]),.Q(B[3]),.Cin(C3),.Sum(Q[3]),.Count(C));             

 

endmodule

5 .用5 . 11节中描述的M U X 4 x 1模块编写1 6 - 1多路选择器的结构化模型。

module MUX16x1(S,Z,D);

input [15:0] D;

input [3:0] S;

output Z;

wire[3:0] ZZ;

 

MUX4x1 MUX1(.Z(ZZ0),.D0(D0),.D1(D1),.D2(D2),.D3(D3),.S0(S0),.S1(S1)),

               MUX2(.Z(ZZ1),.D0(D4),.D1(D5),.D2(D6),.D3(D7),.S0(S0),.S1(S1)),

               MUX3(.Z(ZZ2),.D0(D8),.D1(D9),.D2(D10),.D3(D11),.S0(S0),.S1(S1)),  

               MUX4(.Z(ZZ3),.D0(D12),.D1(D13),.D2(D14),.D3(D15),.S0(S0),.S1(S1)),

               MUX5(.Z(Z),.D0(ZZ0),.D1(DZZ1),.D2(DZZ2),.D3(DZZ3),.S0(S2),.S1(S3));

endmodule

20110615080225011.gif

 

6 .用异步低电平复位描述通用 N位计数器。将通用计数器在实例语句中用作 5位计数器用测试验证程序验证这个5位计数器。

//异步低电平复位描述通用 N位计数器

module n_counter(CLK,nRST,Q,N);

input CLK,nRST;

output [31:0] Q;

input [4:0] N;//最高32位

reg [31:0] Q;

reg [31:0] NN=1;

 

initial

NN<=(NN<<N);

 

always @(posedge CLK or negedge nRST)

begin

if(~nRST)

Q<=0;

else

if (Q<NN)

Q<=Q+1;

else

Q<=0;

end

endmodule

//5位计数器用测试验证程序验证这个5位计数器。

module t_counter(CLK, nRST,Q);

input CLK, nRST;

output [4:0] Q;

reg [4:0] Q;

n_counter    coun1(.CLK(CLK),. nRST (nRST),.Q[0](Q[0]), .Q[1](Q[1]),.Q[2](Q[2]), .Q[3](Q[3]), .Q[4](Q[4]),.N(5));

endmodule

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
10
关闭 站长推荐上一条 /3 下一条