3 Star 26 Fork 6

lanzhoo / TangNano9k_Tutorial

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
Verilog_02.md 5.69 KB
一键复制 编辑 原始数据 按行查看 历史
lanzhoo 提交于 2022-10-02 07:41 . Verilog组合逻辑电路描述简介

Verilog入门(2):组合逻辑

本节通过例子介绍简单组合逻辑电路的描述方法。

step1:通过按键控制LED的亮灭

例子1:通过按键控制LED的亮灭。

实现思路:通过模块的电路图看出,按键1接在FPGA芯片的pin 3。我们需要:

  • 在上节的模块代码中,增加一个输入端口;
  • 在.cst文件中将该端口接到pin 3;
  • 让led0端口和button1端口相连。

具体操作:

1、复制上节的工程目录,改名。

2、编辑top.v,在module的端口列表中增加button1:

module top
(
    input wire button1,
    output wire led0
);

3、编辑tangnano9k.cst,增加key1和引脚3的对应关系:

IO_LOC "button1" 3;
IO_PORT "button1" PULL_MODE=UP;
IO_LOC "led0" 10;
IO_PORT "led0" PULL_MODE=UP DRIVE=8;

4、编辑top.v,将原来的“assign led0 = 0;”修改为:

module top
(
    input wire button1,
    output wire led0
);

    assign led0 = button1;

endmodule

5、烧写,观察

可以看到没按下button1时,led灭;按下时,led亮。

即:button1没按下时,pin3输入高电平;按下时,pin3输入低电平。

6、改为:button1松开亮、按下灭

思路:对button1接非门再接led0。

那么,非门怎么表示呢?试试c语言的求反符号:

    assign led0 = ~button1;

step2:与、或、异或

例子2:通过两个按键的组合状态控制LED的亮灭。

  • 两个按键都按下时亮;
  • 任意一个按下时亮;
  • 仅一个按下时亮;

思路:首先要增加按键端口,查电路图按键0接在引脚4;然后对两个按键进行组合运算。

同样的,试试c语言的位操作表示方式:与、或、异或符号(&、|、^)。

    assign led0 = button1 | button0;

step3:一束线(Vector)(verilog-ieee1364-2001规范:3.3 Vectors)

回顾数电课程中的存储芯片,连接地址总线的有若干个引脚:A0-An,连接数据总线的有若干个引脚:D0-Dn。它们的行为类似,对它们的声明和操作的语句相似。那么我们可以用Vector这个概念对它们同时进行声明和操作。

如果逐个列出来声明和操作不是不行,比如:

wire a0, a1, a2, a3;
assign a0=1;
assign a1=0;
assign a2=1;
assign a3=0;

用Vector的方式表示则是:

wire [3:0] a;
assign a=4'b1010;

注意:这种形式在Verilog里面称为Vector,不是数组,后面会介绍数组的形式。

这里引入两种新的表示方式:[MSB:LSB]和n'b。“wire [3:0] a;”声明变量a代表由4条线组成的线束,每条线可以分别用a[0]、a[1]、a[2]、a[3]表示。

“4'b1010”表示4比特的二进制整数常数,其中“4'”表示线束的宽度,其值为0b1010。要表达同样的值,还可以分别用十进制或十六进制表示为:“4'd10”或者“4'ha”。

再看一个例子:

wire [3:0] a, b, c;
assign a = 4'b1010;
assign b[0] = 1'b0;
assign b[3:1] = a[2:0];
assign c = {1'b1, b[0], a[3:2]};

“assign b[3:1] = a[2:0];”演示对线束中的一部分进行连接,“=”表示将两侧的线束中的线按次序分别连接。等同于:

assign b[3]=a[2];
assign b[2]=a[1];
assign b[1]=a[0];

“{1'b1, b[0], a[3:2]}”表示将若干条线或线束组合起来(大括号表示组合,逗号分割)。“assign c = {1'b1, b[0], a[3:2]};”等同于:

assign c[3]=1'b1;
assign c[2]=b[0];
assign c[1]=a[3];
assign c[0]=a[2];

step4:多束线:数组(Array)(verilog-ieee1364-2001规范:3.10 Arrays)

描述多束相同比特数的线,可以用“数组”表示。例子:

wire [7:0] a[0:2];

表示声明3组8比特的线束:a[0]、a[1]、a[2]。

个人建议比特数目的声明用[MSB:0],数组元素个数的声明用[0:N-1]。虽然Verilog的规范是很灵活,还可以用负数。

step5:线束的组合逻辑(逻辑运算)

多组位数相同(即线数相同)的线束之间的组合逻辑,同样用类同c语言的与、或、非、异或符号和小括号组成表达式进行表示即可。

step6:线束的整数算术运算

线束中各条线的高低电平组成一个多位二进制数,可以被理解为有符号或无符号的整数或小数(定点小数或浮点小数)。

在Verilog中,可以用类同c语言的操作符号进行加减乘除。其中加法和减法可以只用组合逻辑电路表示。下面是无符号整数加法的演示:

module top
(
    input wire [1:0] button,
    output wire [5:0] led
);
    assign led[1:0] = ~button;
    assign led[3:2] = ~(button+2'b01);
    assign led[5:4] = ~(button-2'b01);
endmodule
IO_LOC "led[5]" 16;
IO_PORT "led[5]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[4]" 15;
IO_PORT "led[4]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[3]" 14;
IO_PORT "led[3]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[2]" 13;
IO_PORT "led[2]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[1]" 11;
IO_PORT "led[1]" PULL_MODE=UP DRIVE=8;
IO_LOC "led[0]" 10;
IO_PORT "led[0]" PULL_MODE=UP DRIVE=8;
IO_LOC "button[1]" 3;
IO_PORT "button[1]" PULL_MODE=UP;
IO_LOC "button[0]" 4;
IO_PORT "button[0]" PULL_MODE=UP;

综合、烧写。自行分析两个按键按没按下时6个LED的状态。(注意:按键松开为1、LED低电平亮)

有符号整数的表示有一个关键字signed,以后再介绍。

step7:二选一选择器电路的表示(MUX)

在c语言的赋值语句中有“?”表达式,在Verilog中用同样的形式来表示二选一选择器。

assign y = select ? a : b;

表示当表达式为真时(即非0),y=a;为假时,y=b。

b可以继续用问号表达式来表示从而形成多路选择器:

assign y = select1 ? a : 
               select2 ? b : 
			       select3 ? c : default;

step8:移位

在c语言中移位的符号是“<<”和“>>”,在Verilog中同样用这两个符号表示左移和右移。

在模块中试试这个例子:

    assign led = (~button[1]) ? (~(6'h0c<<2)) :
                     (~button[0]) ? (~(6'h0c>>2)) : (~6'h0c);

step8:比较表达式

等于:(button == 2'b01)

大于:(button > 2'b00)

小于:(button < 2'b10)

还有其它的大于等于、小于等于、不等于自己尝试。

另外还有多个比较表达式之间逻辑与、或、非的表示自己尝试。

上面的语句“(~button[1])”等同于“(button[1]==0)”。

小结

本节简单介绍了如下Verilog关键字和概念:

  • 输入端口的表示方式:“input wire ,”
  • 与、或、非、异或门电路的表示:&、|、~、^
  • Vector:“wire [5:0] led;”
  • Array:“wire [7:0] dataset[0:3]”
  • 多比特常数的表示方法:4'b1001、8'd200、16'ha1b2
  • 多比特位运算:&、|、~、^
  • 无符号整数加减:+、-
  • 无符号整数左移右移:<<、>>
  • 二选一选择器:assign y = select ? a : b;
  • 逻辑表达式:==、<、>、&&、||、...
Verilog
1
https://gitee.com/lanzhoo/TangNano9k_Tutorial.git
git@gitee.com:lanzhoo/TangNano9k_Tutorial.git
lanzhoo
TangNano9k_Tutorial
TangNano9k_Tutorial
master

搜索帮助