Verilog ----基礎7
【例10.1】非流水線方式8 位元元元全加器
module
adder8(cout,sum,ina,inb,cin,clk);
output [7:0] sum;
output cout;
input [7:0]
ina,inb;
input cin,clk;
reg [7:0]
tempa,tempb,sum;
reg cout;
reg tempc;
always @(posedge
clk)
begin
tempa=ina; tempb=inb;
tempc=cin; //輸入資料鎖存
end
always @(posedge clk)
begin
{cout,sum}=tempa+tempb+tempc;
end
endmodule
【例10.2 】4 級流水方式的8 位元元元全加器
module
pipeline(cout,sum,ina,inb,cin,clk);
output [7:0] sum;
output cout;
input [7:0]
ina,inb;
input cin,clk;
reg [7:0]
tempa,tempb,sum;
reg
tempci,firstco,secondco,thirdco,cout;
reg [1:0]
firsts,thirda,thirdb;
reg [3:0]
seconda,secondb,seconds;
reg [5:0]
firsta,firstb,thirds;
always @(posedge clk)
begin
tempa=ina; tempb=inb;
tempci=cin; //輸入資料緩存
end
always @(posedge clk)
begin
{firstco,firsts}=tempa[1:0]+tempb[1:0]+tempci;
//第一級加(低2位)
firsta=tempa[7:2]; //未參加計算的資料緩存
firstb=tempb[7:2];
end
always @(posedge clk)
begin
{secondco,seconds}={firsta[1:0]+firstb[1:0]+firstco,firsts};
//第二級加(第2、3位相加)
seconda=firsta[5:2]; //數據緩存
secondb=firstb[5:2];
end
always @(posedge clk)
begin
{thirdco,thirds}={seconda[1:0]+secondb[1:0]+secondco,seconds};
//第三級加(第4、5位相加)
thirda=seconda[3:2]; //數據緩存
thirdb=secondb[3:2];
end
always @(posedge clk)
begin
{cout,sum}={thirda[1:0]+thirdb[1:0]+thirdco,thirds};
//第四級加(高兩位相加)
end
endmodule
【例10.3 】兩個加法器和一個選擇器的實現方式
module
resource1(sum,a,b,c,d,sel);
parameter size=4;
output [size:0] sum;
input sel;
input [size-1:0]
a,b,c,d;
reg [size:0] sum;
always @(a or b or
c or d or sel)
begin
if (sel)
sum=a+b;
else
sum=c+d;
end
endmodule
【例10.4 】兩個選擇器和一個加法器的實現方式
module
resource2(sum,a,b,c,d,sel);
parameter size=4;
output [size-1:0]
sum;
input sel;
input [size-1:0]
a,b,c,d;
reg [size-1:0]
atemp,btemp;
reg [size:0] sum;
always @(a or b or
c or d or sel)
begin
if (sel)
begin atemp=a; btemp=b;
end
else
begin atemp=c; btemp=d;
end
sum=atemp+btemp;
end
endmodule
【例10.5 】狀態機設計的例子
module FSM(clk,clr,out,start,step2,step3);
input
clk,clr,start,step2,step3;
output [2:0] out;
reg [2:0] out;
reg [1:0]
state,next_state;
parameter state0=2'b00,state1=2'b01,
state2=2'b11,state3=2'b10;
/*狀態編碼,採用格雷(Gray)編碼方式*/
always @(posedge
clk or posedge clr) /*該進程定義起始狀態*/
begin
if
(clr) state <= state0;
else state <= next_state;
end
always @(state or start or step2 or step3) /*該進程實現狀態的轉換*/
begin
case (state)
state0: begin
if (start) next_state <=state1;
else next_state <=state0;
end
state1: begin
next_state <=
state2;
end
state2: begin
if (step2) next_state <=state3;
else next_state <=state0;
end
state3: begin
if (step3) next_state <=state0;
else next_state <=state3;
end
default: next_state <=state0; /*default語句*/
endcase
end
always @(state) /*該進程定義組合邏輯(FSM 的輸出)*/
begin
case (state)
state0: out=3'b001;
state1: out=3'b010;
state2: out=3'b100;
state3: out=3'b111;
default:out=3'b001; /*default語句,避免鎖存器的產生*/
endcase
end
endmodule
【例10.6 】自動轉換量程頻率計控制器
/*信號定義:
clk:
輸入時鐘;
clear: 為整個頻率計的非同步重定信號;
reset: 用來在量程轉換開始時復位計數器;
std_f_sel:
用來選擇標準時基;
cntover:
代表超量程;
cntlow: 代表欠量程。
狀態A,B,C,D,E,F採用一位元熱碼編碼 */
module
control(std_f_sel,reset,clk,clear,cntover,cntlow);
output [1:0]
std_f_sel;
output reset;
input
clk,clear,cntover,cntlow;
reg [1:0]
std_f_sel;
reg reset;
reg [5:0]
present,next; //用於保存當前狀態和次態的中間變數
parameter
start_fl00k=6'b000001, //狀態A 編碼,採用1位元熱碼
fl00k_cnt=6'b000010, //狀態B
start_fl0k=6'b000100, //狀態C
fl0k_cnt=6'b001000, //狀態D
start_flk=6'b010000, //狀態E
flk_cnt=6'b100000; //狀態F
always @(posedge
clk or posedge clear)
begin
if (clear) present<=start_fl0k; //start_fl0k為起始狀態
else present<=next;
end
always @(present or
cntover or cntlow)
begin
case (present) //用case語句描述狀態轉換
start_fl00k: next<=fl00k_cnt;
fl00k_cnt:
begin
if (cntlow) next<=start_fl0k;
else next<=fl00k_cnt;
end
start_fl0k: next<=fl0k_cnt;
fl0k_cnt:
begin
if (cntlow) next<=start_flk;
else if (cntover) next<=start_fl00k;
else
next<=fl0k_cnt;
end
start_flk: next<=flk_cnt;
flk_cnt:
begin
if
(cntover) next<=start_fl0k;
else next<=flk_cnt;
end
default:next<=start_fl0k; //缺省狀態為起始狀態
endcase
end
always @(present) //該進程產生各狀態下的輸出
begin
case (present)
start_fl00k:
begin
reset=1; std_f_sel=2'b00; end
fl00k_cnt:
begin
reset=0; std_f_sel=2'b00; end
start_fl0k:
begin reset=1; std_f_sel=2'b01; end
fl0k_cnt:
begin
reset=0; std_f_sel=2'b01; end
start_flk:
begin
reset=1; std_f_sel=2'b11; end
flk_cnt:
begin reset=0; std_f_sel=2'b11; end
default:
begin reset=1; std_f_sel=2'b01; end
endcase
end
endmodule
【例10.7 】8 位全加器
module add8(sum,cout,b,a,cin);
output [7:0] sum;
output cout;
input [7:0] a,b;
input cin;
assign {cout,sum}=a+b+cin;
endmodule
【例10.8】8 位寄存器
module reg8(qout,in,clk,clear);
output [7:0] qout;
input [7:0] in;
input clk,clear;
reg [7:0] qout;
always @(posedge clk or posedge clear)
begin
if (clear) qout=0; //非同步清0
else qout=in;
end
endmodule
【例10.9 】累加器頂層連接文本描述
module
acc(accout,cout,accin,cin,clk,clear);
output [7:0]
accout;
output cout;
input [7:0] accin;
input
cin,clk,clear;
wire [7:0] sum;
add8
accadd8(sum,cout,accout,accin,cin);
//調用add8 子模組
reg8 accreg8(accout,sum,clk,clear); //調用reg8 子模組
endmodule
【例10.10】用`include 描述的累加器
`include “add8.v”;
`include “reg8.v”;
module
accn(accout,cout,accin,cin,clk,clear);
output [7:0]
accout;
output cout;
input [7:0] accin;
input cin,clk,clear;
wire [7:0] sum;
add8
accadd8(sum,cout,accout,accin,cin);
//調用add8 子模組
reg8
accreg8(accout,sum,clk,clear); //調用reg8 子模組
endmodule
【例10.11】阻塞賦值方式描述的移位寄存器1
module block1(Q0,Q1,Q2,Q3,din,clk);
output Q0,Q1,Q2,Q3;
input clk,din;
reg Q0,Q1,Q2,Q3;
always @(posedge clk)
begin
Q3=Q2; //注意賦值語句的順序
Q2=Q1;
Q1=Q0;
Q0=din;
end
endmodule
【例10.12】阻塞賦值方式描述的移位寄存器2
module block2(Q0,Q1,Q2,Q3,din,clk);
output Q0,Q1,Q2,Q3;
input clk,din;
reg Q0,Q1,Q2,Q3;
always @(posedge clk)
begin
Q3=Q2;
Q1=Q0; //該句與下句的順序與例10.11顛倒
Q2=Q1;
Q0=din;
end
endmodule
【例10.13】阻塞賦值方式描述的移位寄存器3
module block3(Q0,Q1,Q2,Q3,din,clk);
output Q0,Q1,Q2,Q3;
input clk,din;
reg Q0,Q1,Q2,Q3;
always @(posedge clk)
begin
Q0=din;//4條賦值語句的順序與例10.11 完全顛倒
Q1=Q0;
Q2=Q1;
Q3=Q2;
end
endmodule
【例10.14】非阻塞賦值方式描述的移位寄存器
module
block4(Q0,Q1,Q2,Q3,din,clk);
output
Q0,Q1,Q2,Q3;
input
clk,din;
reg
Q0,Q1,Q2,Q3;
always @(posedge clk)
begin
Q3<=Q2;
Q1<=Q0;
Q2<=Q1;
Q0<=din;
end
endmodule
【例10.15】長幀同步時鐘的產生
module longframe1(clk,strb);
parameter delay=8;
input clk;
output strb;
reg strb;
reg [7:0] counter;
always@(posedge clk)
begin
if (counter==255) counter=0;
else counter=counter+1;
end
always@(counter)
begin
if (counter<=(delay-1)) strb=1;
else
strb=0;
end
endmodule
【例10.16】引入了D 觸發器的長幀同步時鐘的產生
module longframe2(clk,strb);
parameter delay=8;
input clk;
output strb;
reg [7:0] counter;
reg temp;
reg strb;
always@(posedge clk)
begin
if (counter==255) counter=0;
else counter=counter+1;
end
always@(posedge clk)
begin
strb=temp; //引入一個觸發器
end
always@(counter)
begin
if (counter<=(delay-1)) temp=1;
else temp=0;
end
endmodule
沒有留言:
張貼留言