使用ModelSim创建一个工程的步骤

1,打开 ModelSim 的画面如下:

2,建立工程,如图所示:

单击 Project 之后,画面如下:

在图中 Project Name 中输入 AND_2,这也是我们建立的第一个工程,路径选择如下图

所示,默认库名我们用默认的 work

这一步完成之后,点击 ok,如下图:

单击 ok 后,如下图:

单击 Add items to the Project 中的 Creat New File(如果你已经写好了代

码,可以通过点击 Add Existing Flie 添加),如下图:

File Name 中输入 AND_2,在 Add file as type 选项中选择 Verilog,其他的使用默认即

可。单击 ok

在工作空间中添加了名为 AND_2 的文件,如图。

Step1:创建新工程

        通过File→New→Project菜单命令创建一个新工程

Step2:在Project Name文本框中填写项目名称,这里输入adder_tb。Project Location是工作目录,可通过Browse按钮来选择或改变。ModelSim不能为一个工程自动建立一个目录,因此最好自己定义保存路径。

Step3:向工程中添加文件
Step4:使用Browse按钮选择向工程添加之前已经在QuartusⅡ中编译好的的源文件adder.v和测试文件adder_tb.v,这里的文件类型为默认,单击OK按钮完成文件的添加。

Step5:编译文件。工程窗口的文件名上单击右键,选择Compile→Compile All命令来整体编译模块文件及测试文件。若编译成功,则Project中文件的Status(状态)栏中显示标记“√”。

Verilog HDL 中有两类数据类型:线网数据类型和寄存器数据类型。线网类型表示构件间

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

Verilog 最常用的 2 种数据类型就是线网(wire)与寄存器(reg),其余类型可以理解为这两种数据类型的扩展或辅助。

一、线网(wire)

wire 类型表示硬件单元之间的物理连线,由其连接的器件输出端连续驱动。如果没有驱动元件连接到 wire 型变量,缺省值一般为 "Z"。

线网型还有其他数据类型,包括 wand,wor,wri,triand,trior,trireg 等。

二、寄存器(reg)

寄存器(reg)用来表示存储单元,它会保持数据原有的值,直到被改写。

三、向量

当位宽大于 1 时,wire 或 reg 即可声明为向量的形式。

Verilog 支持可变的向量域选择

四、整数,实数,时间寄存器变量

整数,实数,时间等数据类型实际也属于寄存器类型。

整数(integer)

实数(real)

实数用关键字 real 来声明,可用十进制或科学计数法来表示。实数声明不能带有范围,默认值为 0。如果将一个实数赋值给一个整数,则只有实数的整数部分会赋值给整数。

时间(time)

Verilog 使用特殊的时间寄存器 time 型变量,对仿真时间进行保存。其宽度一般为 64 bit,通过调用系统函数 $time 获取当前仿真时间。

五、数组

在 Verilog 中允许声明 reg, wire, integer, time, real 及其向量类型的数组。

数组维数没有限制。线网数组也可以用于连接实例模块的端口。数组中的每个元素都可以作为一个标量或者向量,以同样的方式来使用,形如:<数组名>[<下标>]。对于多维数组来讲,用户需要说明其每一维的索引。

六、存储器

存储器变量就是一种寄存器数组,可用来描述 RAM 或 ROM 的行为。

七、参数

参数用来表示常量,用关键字 parameter 声明,只能赋值一次。

八、字符串

字符串保存在 reg 类型的变量中,每个字符占用一个字节(8bit)。因此寄存器变量的宽度应该足够大,以保证不会溢出。

实验四 简单运算器的设计与仿真

VerilogHDL代码:

module fadd(a,b,s,ci,co);

   input a,b,ci;

   output s,co;

   reg s,co;

   always@(a or b or ci)

   begin

    s<=(a&~b&~ci)|(~a&b&~ci)|(~a&~b&ci)|(a&b&ci);

    co<=(a&b)|(a&ci)|(b&ci);

   end

endmodule

 module add(a,b,sub,s,c,v,n);

  input [31:0]a;

  input [31:0]b;

  input sub;

  output [31:0]s;

  output c,v,n;

  wire[31:0]a;

  wire[31:0]b;

  wire

  c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31;

  fadd f0(a[0],b[0]^sub,s[0],sub,c1);

  fadd f1(a[1],b[1]^sub,s[1],c1,c2);

  fadd f2(a[2],b[2]^sub,s[2],c2,c3);

  fadd f3(a[3],b[3]^sub,s[3],c3,c4);

  fadd f4(a[4],b[4]^sub,s[4],c4,c5);

  fadd f5(a[5],b[5]^sub,s[5],c5,c6);

  fadd f6(a[6],b[6]^sub,s[6],c6,c7);

  fadd f7(a[7],b[7]^sub,s[7],c7,c8);

  fadd f8(a[8],b[8]^sub,s[8],c8,c9);

  fadd f9(a[9],b[9]^sub,s[9],c9,c10);

  fadd f10(a[10],b[10]^sub,s[10],c10,c11);

  fadd f11(a[11],b[11]^sub,s[11],c11,c12);

  fadd f12(a[12],b[12]^sub,s[12],c12,c13);

  fadd f13(a[13],b[13]^sub,s[13],c13,c14);

  fadd f14(a[14],b[14]^sub,s[14],c14,c15);

  fadd f15(a[15],b[15]^sub,s[15],c15,c16);

  fadd f16(a[16],b[16]^sub,s[16],c16,c17);

  fadd f17(a[17],b[17]^sub,s[17],c17,c18);

  fadd f18(a[18],b[18]^sub,s[18],c18,c19);

  fadd f19(a[19],b[19]^sub,s[19],c19,c20);

  fadd f20(a[20],b[20]^sub,s[20],c20,c21);

  fadd f21(a[21],b[21]^sub,s[21],c21,c22);

  fadd f22(a[22],b[22]^sub,s[22],c22,c23);

  fadd f23(a[23],b[23]^sub,s[23],c23,c24);

  fadd f24(a[24],b[24]^sub,s[24],c24,c25);

  fadd f25(a[25],b[25]^sub,s[25],c25,c26);

  fadd f26(a[26],b[26]^sub,s[26],c26,c27);

  fadd f27(a[27],b[27]^sub,s[27],c27,c28);

  fadd f28(a[28],b[28]^sub,s[28],c28,c29);

  fadd f29(a[29],b[29]^sub,s[29],c29,c30);

  fadd f30(a[30],b[30]^sub,s[30],c30,c31);

  fadd f31(a[31],b[31]^sub,s[31],c31,c);

  assign n=s[31];

  assign v=c^c31;

endmodule

 module mux21_32(f,a,b,s);

  output[31:0] f;

  input[31:0] a,b;

  input s;

  reg[31:0] f;

  always @(s or a or b)

  case(s)

    1'd0: f=a;

    1'd1: f=b;

  endcase

endmodule

 module ALU(op,a,b,s,n,v,c,z);

  input [1:0]op;

  input [31:0]a,b;

  output[31:0]s;

  output n,v,c,z;

  wire [31:0]d,e,f,s1;

  assign d=a&b;

  assign e=a|b;

  mux21_32 u0(f,d,e,op[0]);

  add u2(a,b,op[0],s1,c,v,n);

  mux21_32 u1(s,f,s1,op[1]);

  assign z=~(|s);

endmodule

测试代码:

`timescale 1ns/1ns

module ALUtest;

  reg clk;

  reg[1:0]op;

  reg[31:0]a,b;

  wire[31:0]s;

  wire n,v,c,z;

  ALU A(op,a,b,s,n,v,c,z);

  initial clk=1;

  always#50 clk=~clk;

  initial

  begin

    #20   a=32'b0100_0101_0100_0000_0010_0010_0101_0001;

          b=32'b1010_0101_0010_0000_0100_0010_0011_0010;

    #100  a=32'b0100_0101_0100_0000_0010_0010_0101_0001;

          b=32'b1010_0101_0010_0000_0100_0010_0011_0010;

          op=2'b01;

    #100  a=32'b0100_0101_0100_0000_0010_0010_0101_0001;

          b=32'b1010_0101_0010_0000_0100_0010_0011_0010;

          op=2'b10;

    #100  a=32'b0100_0101_0100_0000_0010_0010_0101_0001;

          b=32'b1010_0101_0010_0000_0100_0010_0011_0010;

          op=2'b11;

    #100  a=32'b0111_1011_1101_1110_1111_1111_1111_1111;

          b=32'b0111_1011_1101_1110_1111_1111_1111_1111;

          op=2'b11;

    #100  a=32'd15;

          b=32'd9;

          op=2'b11;

    #100  a=32'd9;

          b=32'd15;

          op=2'b11;

    #100  $stop;

  end

endmodule

序号

输入数据

仿真结果

仿真结果是否正确

1

a=32'h45402251;

b=32'hA5204232;op=2'b00

S=32'h05000210;n=1'b1;z=1'b0;v=1'b0;c=1'b0

正确

2

a=32'h45402251;

b=32'hA5204232;op=2'b01

S=32'he5606273;n=1'b1;z=1'b0;v=1'b1;c=1'b0

正确

3

a=32'h45402251;

b=32'hA520-4232;op=2'b10

S=32'hea606483;n=1'b1;z=1'b0;v=1'b0;c=1'b0

正确

4

a=32'h45402251; b=32'hA5204232;op=2'b11

S=32'ha01feo1f;n=1'b1;z=1'b0;v=1'b0;c=1'b0

正确

实验六 八位比较器的设计与仿真

Verilog代码:

module compare(a,b,out);

input [7:0] a,b;

output out;

assign out=(a[7:0]>b[7:0])?1:0;

endmodule

仿真代码:

`timescale 1ns/1ns

`include "./compare.v"

module comparetest;

  reg[7:0] a,b;

  wire equal;

  initial

  begin

    a='b00000000;

    b='b00000000;

    #100 a='b00000000;b='b00000001;

    #100 a='b00010001;b='b00000011;

    #100 a='b00000001;b='b00000010;

    #100 a=100;b=99;

    #100 a=123;b=125;

    #100 a=135;b=130;

    #100 a=245;b=246;

    #100 $stop;

  end

  compare compare(.out(out),.a(a),.b(b));

Endmodule

实验七 1/2分频器的设计与仿真

VerilogHDL代码:

module half_clk_dai(

    clk_in,

    rst,

    clk_out

    );

input clk_in;

input rst;

output clk_out;

reg clk_out;

always @(posedge clk_in or negedge rst)

  begin

    if(!rst)

      clk_out<=0;

    else

      clk_out<=~clk_out;

  end

endmodule

Test bench仿真代码:

`timescale 1ns/1ns  

module main;  

  reg clk_in;

  reg rst;

  initial

  begin

    clk_in=1;

    rst=1;

    #1000

    rst=0;

    #1000

    rst=1;

  end    

  always #200 clk_in=~clk_in;

  half_clk_dai dai1(

    .clk_in(clk_in),

    .rst(rst),

    .clk_out(clk_out)

  );

endmodule  

实验九 四选一多路选择器的设计与仿真

VerilogHDL代码:

module choose4(out,i0,i1,i2,i3,s1,s0);

output out;

input i0,i1,i2,i3;

input s1,s0;

reg out;

always @(s1 or s0 or i0 or i1 or i2 or i3)

begin

   case({s1,s0})

     2'b00: out = i0;

     2'b01: out = i1;

     2'b10: out = i2;

     2'b11: out = i3;

     default:out=1'bx;

   endcase

   end

endmodule

Test bench仿真代码:

module choose4_t;

reg i0,i1,i2,i3;

reg s1,s0;

wire out;

choose4 unit(

.i0(i0),

.i1(i1),

.i2(i2),

.i3(i3),

.s1(s1),

.s0(s0),

.out(out)

);

initial

begin

i0=2'b00;

i1=2'b01;

i2=2'b10;

i3=2'b11;

s1=1'b0;s0=1'b0;

#20

s1=1'b0;s0=1'b1;

#20

s1=1'b1;s0=1'b0;

#20

s1=1'b1;s0=1'b1;

#20;

end

endmodule

实验十一 触发器的设计与仿真

module register_right(clk, din, dout);  

     input clk;  

     input [15:0] din;  

     output [15:0] dout;  

     reg [15:0] dout;  

     always @(posedge clk)  

         begin  

             dout <= {din[0], din[15:1]};  

        end  

endmodule  

 `timescale 1ns/1ps  

 module register_right_tb;  

     reg clk;  

     reg [15:0] din;  

     wire [15:0] dout;  

     always  

         begin  

         #10 clk = ~clk;  

         end  

    initial  

        begin  

            clk = 1'b0;  

            din = 16'b0000_0000_0000_0000;  

            #10 din = 16'b0000_0000_0000_1011;  

            #20 din = 16'b0000_0000_0111_0000;  

            #20 din = 16'b0000_0000_0000_0011;  

            #100;  

        end  

     register_right U1(.clk(clk), .din(din), .dout(dout));  

 endmodule

实验题目 16位左移寄存器

 module register_left(clk, din, dout);  

     input clk;  

     input [15:0] din;  

     output [15:0] dout;  

     reg [15:0] dout;    

     always @(posedge clk)  

         begin  

             dout <= {din[14:0], din[15]};  

         end  

endmodule  

 `timescale 1ns/1ps  

 module register_left_tb;  

     reg clk;  

     reg [15:0] din;  

     wire [15:0] dout;    

     always  

         #10 clk = ~clk;  

     initial  

         begin  

             clk = 1'b0;  

             din = 16'b0000_0000_0000_0000;  

             #10 din = 16'b0000_0000_0000_0011;  

             #20 din = 16'b0000_0000_0011_0000;  

             #100;

         end

     register_left U1(.clk(clk), .din(din), .dout(dout));  

 endmodule  

在HDL的建模中,主要有结构化描述方式、数据流描述方式和行为描述方式。

1结构化描述方式

结构化的建模方式就是通过对电路结构的描述来建模,即通过对器件的调用(HDL概念称为例化),并使用线网来连接各器件的描述方式。这里的器件包括Verilog HDL的内置门如与门and,异或门xor等,也可以是用户的一个设计。结构化的描述方式反映了一个设计的层次结构。

2数据流描述方式

数据流的建模方式就是通过对数据流在设计中的具体行为的描述的来建模。最基本的机制就

是用连续赋值语句。在连续赋值语句中,某个值被赋给某个线网变量(信号),语法如下:

assign [delay] net_name = expression;

如:assign #2 A = B;

在数据流描述方式中,还必须借助于HDL提供的一些运算符,如按位逻辑运算符 :逻辑与 (&),逻辑或(|)等。

3行为描述方式

行为方式的建模是指采用对信号行为级的描述(不是结构级的描述)的方法来建模。在表示

方面,类似数据流的建模方式,但一般是把用initial 块语句或always 块语句描述的归为行为建模方式。行为建模方式通常需要借助一些行为级的运算符如加法运算符(+),减法运算符(-)等。

(1)

?<(小于)

(2)

&& (逻辑与)

(3)

 ?^(二元异或):(相当于异或门运算)

(4) 条件运算符

条件操作符根据条件表达式的值选择表达式,形式如下:

cond_expr ? expr1 : expr2

如果cond_expr 为真(即值为1 ),选择expr1 ;如果cond_expr 为假(值为0 ),选择expr2 。如果 cond_expr x z ,结果将是按以下逻辑expr1 expr2 按位操作的值: 0 0 0 1 11 ,其

余情况为x

(5) 连接运算符

连接操作是将小表达式合并形成大表达式的操作。形式如下:

{expr1, expr2, . . .exprN}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青竹小轩_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值