Verilog ----基礎2
【例5.1】用case 語句描述的4 選 1 資料選擇器
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
【例5.2 】同步置數、同步清零的計數器
module count(out,data,load,reset,clk);
output [7:0] out;
input [7:0] data;
input load,clk,reset;
reg [7:0] out;
always @(posedge clk) //clk上升沿觸發
begin
if (!reset) out = 8'h00; //同步清0,低電平有效
else if (load) out = data; //同步預置
else out = out + 1; //計數
end
endmodule
【例5.3 】用always 過程語句描述的簡單算術邏輯單元
`define add 3'd0
`define minus 3'd1
`define band 3'd2
`define bor 3'd3
`define bnot 3'd4
module alu(out,opcode,a,b);
output [7:0] out;
reg [7:0] out;
input [2:0] opcode; //操作碼
input [7:0] a,b; //運算元
always@(opcode or a or b) //電平敏感的always 塊
begin
case (opcode)
`add: out = a+b; //加操作
`minus: out = a-b; //減操作
`band: out = a&b; //求與
`bor: out = a|b; //求或
`bnot: out=~a; //求反
default: out=8'hx; //未收到指令時,輸出任意態
endcase
end
endmodule
【例5.4 】用initial 過程語句對測試變數A、B、C 賦值
`timescale 1ns/1ns
module test;
reg A,B,C;
initial
begin
A = 0;
B = 1; C = 0;
#50 A = 1; B = 0;
#50 A = 0; C = 1;
#50
B = 1;
#50
B = 0; C = 0;
#50
$finish ;
end
endmodule
【例5.5 】用begin-end 串列塊產生信號波形
`timescale 10ns/1ns
module wave1;
reg wave;
parameter cycle=10;
initial
begin
wave=0;
#(cycle/2)
wave=1;
#(cycle/2)
wave=0;
#(cycle/2)
wave=1;
#(cycle/2)
wave=0;
#(cycle/2)
wave=1;
#(cycle/2)
$finish ;
end
initial
$monitor($time,,,"wave=%b",wave);
endmodule
【例5.6 】用fork-join 並行塊產生信號波形
`timescale 10ns/1ns
module wave2;
reg wave;
parameter cycle=5;
initial
fork
wave=0;
#(cycle)
wave=1;
#(2*cycle)
wave=0;
#(3*cycle)
wave=1;
#(4*cycle)
wave=0;
#(5*cycle)
wave=1;
#(6*cycle)
$finish;
join
initial
$monitor($time,,,"wave=%b",wave);
endmodule
【例5.7 】持續賦值方式定義的2 選 1 多路選擇器
module MUX21_1(out,a,b,sel);
input a,b,sel;
output out;
assign out=(sel==0)?a:b;
//持續賦值,如果sel 為0,則out=a ;否則out=b
endmodule
【例5.8】阻塞賦值方式定義的2 選 1 多路選擇器
module MUX21_2(out,a,b,sel);
input a,b,sel;
output out;
reg out;
always@(a or b or sel)
begin
if (sel==0) out=a; //阻塞賦值
else out=b;
end
endmodule
【例5.9 】非阻塞賦值
module non_block(c,b,a,clk);
output c,b;
input clk,a;
reg c,b;
always @(posedge clk)
begin
b<=a;
c<=b;
end
endmodule
【例5.10】阻塞賦值
module block (c,b,a,clk);
output c,b;
input clk,a;
reg c,b;
always @(posedge clk)
begin
b=a;
c=b;
end
endmodule
【例5.11】模為60 的BCD 碼加法計數器
module
count60(qout,cout,data,load,cin,reset,clk);
output [7:0] qout;
output cout;
input [7:0] data;
input load,cin,clk,reset;
reg [7:0] qout;
always @(posedge clk) //clk上升沿時刻計數
begin
if
(reset) qout<=0; //同步復位
else
if (load) qout<=data; //同步置數
else
if (cin)
begin
if (qout[3:0]==9) //低位是否為 9,是則
begin
qout[3:0]<=0; //回0,並判斷高位是否為5
if (qout[7:4]==5) qout[7:4]<=0;
else
qout[7:4]<=qout[7:4]+1; //高位不為5,則加1
end
else //低位不為 9,則加1
qout[3:0]<=qout[3:0]+1;
end
end
assign cout=((qout==8'h59)&cin)?1:0; //產生進位元輸出信號
endmodule
【例5.12】BCD 碼—七段數碼管顯示解碼器
module decode4_7(decodeout,indec);
output [6:0]
decodeout;
input [3:0] indec;
reg [6:0]
decodeout;
always @(indec)
begin
case (indec) //用case語句進行解碼
4'd0:decodeout=7'b1111110;
4'd1:decodeout=7'b0110000;
4'd2:decodeout=7'b1101101;
4'd3:decodeout=7'b1111001;
4'd4:decodeout=7'b0110011;
4'd5:decodeout=7'b1011011;
4'd6:decodeout=7'b1011111;
4'd7:decodeout=7'b1110000;
4'd8:decodeout=7'b1111111;
4'd9:decodeout=7'b1111011;
default: decodeout=7'bx;
endcase
end
endmodule
【例5.13】用casez 描述的資料選擇器
module mux_casez(out,a,b,c,d,select);
output out;
input a,b,c,d;
input [3:0] select;
reg out;
always @(select or a or b or c or d)
begin
casez (select)
4'b???1: out = a;
4'b??1?: out = b;
4'b?1??: out = c;
4'b1???: out = d;
endcase
end
endmodule
【例5.14】隱含鎖存器舉例
module
buried_ff(c,b,a);
output c;
input b,a;
reg c;
always @(a or b)
begin
if ((b==1)&&(a==1)) c=a&b;
end
endmodule
【例5.15】用for 語句描述的七人投票表決器
module
voter7(pass,vote);
output pass;
input [6:0] vote;
reg [2:0] sum;
integer i;
reg pass;
always @(vote)
begin
sum=0;
for (i=0;i<=6;i=i+1) //for語句
if (vote[i]) sum=sum+1;
if (sum[2])
pass=1; //若超過4人贊成,則pass=1
else pass=0;
end
endmodule
【例5.16】用for 語句實現2 個8 位數相乘
module
mult_for(outcome,a,b);
parameter size=8;
input [size:1] a,b; //兩個運算元
output [2*size:1]
outcome; //結果
reg [2*size:1]
outcome;
integer i;
always @(a or b)
begin
outcome=0;
for (i=1; i<=size; i=i+1) //for語句
if (b[i])
outcome=outcome +(a <<
(i-1));
end
endmodule
【例5.17】用repeat 實現8 位二進位數字的乘法
module mult_repeat
(outcome,a,b);
parameter size=8;
input [size:1] a,b;
output [2*size:1]
outcome;
reg [2*size:1]
temp_a,outcome;
reg [size:1]
temp_b;
always @(a or b)
begin
outcome=0;
temp_a=a;
temp_b=b;
repeat (size) //repeat語句,size 為迴圈次數
begin
if (temp_b[1])
//如果temp_b 的最低位為1,就執行下面的加法
outcome=outcome+temp_a;
temp_a=temp_a<<1; //運算元a左移一位
temp_b=temp_b>>1; //運算元b 右移一位
end
end
endmodule
【例5.18】同一迴圈的不同實現方式
module loop1; //方式1
integer i;
initial
for (i=0;i<4;i=i+1) //for語句
begin
$display(“i=%h”,i);
end
endmodule
module loop2; //方式2
integer i;
initial begin
i=0;
while (i<4) //while語句
begin
$display ("i=%h",i);
i=i+1;
end
end
endmodule
module loop3; //方式3
integer i;
initial begin
i=0;
repeat (4) //repeat語句
begin
$display ("i=%h",i);
i=i+1;
end
end
endmodule
【例5.19】使用了`include 語句的
16 位加法器
`include "adder.v"
module
adder16(cout,sum,a,b,cin);
output cout;
parameter my_size=16;
output [my_size-1:0] sum;
input [my_size-1:0] a,b;
input cin;
adder my_adder(cout,sum,a,b,cin); //調用adder模組
endmodule
//下面是adder模組代碼
module
adder(cout,sum,a,b,cin);
parameter size=16;
output cout;
output [size-1:0] sum;
input cin;
input [size-1:0] a,b;
assign {cout,sum}=a+b+cin;
endmodule
【例5.20 】條件編譯舉例
module
compile(out,A,B);
output out;
input A,B;
`ifdef
add //宏名為add
assign out=A+B;
`else
assign out=A-B;
`endif
endmodule
沒有留言:
張貼留言