数字电路(第三部分:Verilog设计)
语法
模块定义:module 模块名(端口1,端口2,端口3,...);
模块定义结束:endmodule
I/O说明:输入 input 端口名1,端口名2,...,端口名N;
,输出 output 端口名1,端口名2,...,端口名N;
register型变量(在always块中被赋值的信号)定义:reg 数据名1,数据名2,...,数据名n;
。定义8位宽的数据:reg[7:0] data;
assign语句:assign 方程式;
,一般适合于对组合逻
辑 进行赋值。
数字:<位宽>'<进制> <数字>
位宽为对应二进制数的宽度;十进制的数可以缺省位宽和进制说明(二进制b,十六进制h);x代表不定值,z代表高阻值。
if-else
语句、case-endcase
语句,要在always块内;如执行的语句为多句时,要用begin-end
语句括起来。
位拼接运算符 { }
:将两个或多个信号的某些位拼接起来,如{信号1的某几位,信号2的某几位,...,信号n的某几位}
always块
当括号内的表达式的值改变时,就会执行一遍块内语句。(一般用于时序逻辑 )
1 2 3 4 5 6 always @(...) begin end
posedge与negedge关键字:事件由时钟边沿触发,分别表示信号的上升沿和下降沿。如:
1 2 always @(posedge clk) always @(negedge clk)
always块内是按照指定的顺序执行的;两个或更多个always块之间、always块与assign语句之间,是同时执行(并行执行)的。
设计举例
4位全加器
1 2 3 4 5 6 7 module add4(cout, sum, a, b, cin); output cout; output [3 :0 ] sum; input [3 :0 ] a, b; input cin; assign {cout, sum} = a + b + cin; endmodule
3-8译码器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 module decoder_38(out,in,en); output [7 :0 ] out; input [2 :0 ] in; input en; reg [7 :0 ] out; always @(in or en) begin if (en) out=8'b11111111 ; else case (in) 3'b000 : out=8'b11111110 ; 3'b001 : out=8'b11111101 ; 3'b010 : out=8'b11111011 ; 3'b011 : out=8'b11110111 ; 3'b100 : out=8'b11101111 ; 3'b101 : out=8'b11011111 ; 3'b110 : out=8'b10111111 ; 3'b111 : out=8'b01111111 ; endcase end endmodule
4位同步清0、同步预置 二进制计数器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 module counter4(out, cout, data, load, clr, clk); output [3 :0 ] out; output cout; input [3 :0 ] data; input load, clr, clk; reg [3 :0 ] out; always @(posedge clk) begin if (!clr) out=0 ; else if (load) out=data; else out=out+1 ; end assign cout=&out; endmodule
4位异步清0、同步预置 二进制计数器(注意这里异步清零的方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 module counter4(out, cout, data, load, clr, clk); output [3 :0 ] out; output cout; input [3 :0 ] data; input load, clr, clk; reg [3 :0 ] out; always @(posedge clk) begin if (load) out=data; else out=out+1 ; end always @(clr) begin if (!clr) out=0 ; end assign cout=&out; endmodule
4位同步清0、同步预置 十进制计数器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 module counter10(out,cout,data,load,clr,clk); output [3 :0 ] out; output cout; input [3 :0 ] data; input load, clr, clk; reg [3 :0 ] out; always @(posedge clk) begin if (!clr) out=0 ; else if (load) out=data; else if (out==9 ) out=0 ; else out=out+1 ; end assign cout = (out==9 ) ? 1 : 0 ; endmodule
4位异步清0、同步预置 十进制计数器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 module counter10(out,cout,data,load,clr,clk); output [3 :0 ] out; output cout; input [3 :0 ] data; input load, clr, clk; reg [3 :0 ] out; always @(posedge clk) begin if (load) out=data; else if (out==9 ) out=0 ; else out=out+1 ; end always @(clr) begin if (!clr) out=0 ; end assign cout = (out==9 ) ? 1 : 0 ; endmodule
8位移位寄存器(同步清0,左移)
1 2 3 4 5 6 7 8 9 10 11 12 13 module shifter8(dout, din, clk, clr); output [7 :0 ] dout; input din, clk, clr; reg [7 :0 ] dout; always @(posedge clk) begin if (clr) dout=0 ; else begin dout=dout<<1 ; dout[0 ]=din; end end endmodule
▲ 4选1数据选择器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 module mux4_1(out, in0, in1, in2, in3, sel); output out; input in0,in1,in2,in3; input [1 :0 ] sel; reg out; always @(in0 or in1 or in2 or in3 or sel) case (sel) 2'b00 : out=in0; 2'b01 : out=in1; 2'b10 : out=in2; 2'b11 : out=in3; default : out=2'bx ; endcase endmodule
▲ 可变模k加法/减法计数器(同步清0,同步预置)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 module updown_count(data, clk, clr, load, up_down, out, cout); input [7 :0 ] data; input clk, clr, load; input up_down; output [7 :0 ] out; output cout; reg [7 :0 ] out; reg cout; always @(posedge clk) begin if (!clr) out = 0 ; else if (load) out = data; else if (up_down) begin if (out==k-1 ) begin out = 0 ; cout = 1 ; end else begin out = out + 1 ; cout = 0 ; end end else begin if (out==0 ) begin out = k-1 ; cout = 1 ; end else begin out = out - 1 ; cout = 0 ; end end end endmodule