1. 非流水线方式8 位全加器 ............................................................................... 2 2. 4 级流水方式的 8 位全加器 ........................................................................... 2 3. 两个加法器和一个选择器的实现方式 ................................................................ 4 4. 两个选择器和一个加法器的实现方式 ................................................................ 4 5. 状态机设计的例子 .......................................................................................... 5 6. 自动转换量程频率计控制器 ............................................................................. 6 7. 8 位全加器 .................................................................................................... 9 8. 8 位寄存器 .................................................................................................... 9 9. 累加器顶层连接文本描述 .............................................................................. 10 10. 用`include 描述的累加器 .............................................................................. 10 11. 阻塞赋值方式描述的移位寄存器 1 ................................................................. 11 12. 阻塞赋值方式描述的移位寄存器2 .................................................................. 11 13. 阻塞赋值方式描述的移位寄存器3 .................................................................. 12 14. 非阻塞赋值方式描述的移位寄存器 ................................................................. 12 15. 长帧同步时钟的产生 ..................................................................................... 12 16. 引入了D 触发器的长帧同步时钟的产生 ......................................................... 13 17. 数字跑表 ...................................................................................................... 14 18. 4 位数字频率计控制模块 .............................................................................. 16 19. 4 位数字频率计计数子模块 ........................................................................... 17 20. 频率计锁存器模块 ........................................................................................ 17 21. 交通灯控制器 ............................................................................................... 18 22. “梁祝”乐曲演奏电路 .................................................................................. 21 23. 自动售饮料机 ............................................................................................... 26
1
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
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;
2
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
3
always @(posedge clk) begin
{cout,sum}={thirda[1:0]+thirdb[1:0]+thirdco,thirds}; //第四级加(高两位相加) end endmodule
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
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)
4
begin
if(sel)begin atemp=a; btemp=b; end else begin atemp=c; btemp=d; end sum=atemp+btemp; end endmodule
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;
5
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
6. 自动转换量程频率计控制器
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为起始状态
7
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
8
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
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
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)
9
begin
if(clear) qout=0; //异步清 0 else qout=in; end endmodule
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. 用`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
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
11
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
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
15. 长帧同步时钟的产生
module longframe1(clk,strb); parameter delay=8;
12
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
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;
13
end
always@(posedge clk) begin
strb=temp; //引入一个触发器 end always@(counter) begin
if(counter<=(delay-1)) temp=1; else temp=0; end endmodule
17. 数字跑表
/*信号定义:
CLK: CLK为时钟信号; CLR: 为异步复位信号; PAUSE: 为暂停信号;
MSH,MSL: 百分秒的高位和低位; SH,SL: 秒信号的高位和低位; MH,ML: 分钟信号的高位和低位。 */
module paobiao(CLK,CLR,PAUSE,MSH,MSL,SH,SL,MH,ML); input CLK,CLR; input PAUSE;
output[3:0] MSH,MSL,SH,SL,MH,ML; reg[3:0] MSH,MSL,SH,SL,MH,ML;
reg cn1,cn2; //cn1为百分秒向秒的进位,cn2为秒向分的进位 //百分秒计数进程,每计满 100,cn1产生一个进位 always @(posedge CLK or posedge CLR)
14
begin
if(CLR) begin //异步复位 {MSH,MSL}<=8'h00; cn1<=0; end
else if(!PAUSE) //PAUSE为 0时正常计数,为 1时暂停计数 begin
if(MSL==9) begin MSL<=0; if(MSH==9)
begin MSH<=0; cn1<=1; else MSH<=MSH+1; end else begin
MSL<=MSL+1; cn1<=0; end end end
//秒计数进程,每计满 60,cn2产生一个进位 always @(posedge cn1 or posedge CLR) begin
if(CLR)begin //异步复位 {SH,SL}<=8'h00; cn2<=0; end
else if(SL==9) //低位是否为 9 begin SL<=0;
15
end if(SH==5) begin SH<=0; cn2<=1; end else SH<=SH+1; end else
begin SL<=SL+1; cn2<=0; end end
//分钟计数进程,每计满 60,系统自动清零 always @(posedge cn2 or posedge CLR) begin if(CLR)
begin {MH,ML}<=8'h00; end //异步复位 else if(ML==9) begin ML<=0;
if(MH==5) MH<=0; else MH<=MH+1; end else ML<=ML+1; end
endmodule
18. 4 位数字频率计控制模块
module fre_ctrl(clk,rst,count_en,count_clr,load); output count_en,count_clr,load; input clk,rst; reg count_en,load; always @(posedge clk) begin
if(rst)begin count_en=0; load=1; end
16
else begin
count_en=~count_en;
load=~count_en; //load信号的产生 end end
assign count_clr=~clk&load; //count_clr信号的产生 endmodule
19. 4 位数字频率计计数子模块
module count10(out,cout,en,clr,clk); output[3:0] out; output cout; input en,clr,clk; reg[3:0] out;
always @(posedge clk or posedge clr) begin
if (clr) out = 0; //异步清 0 else if(en) begin
if(out==9) out=0; else out = out+1; end end
assign cout =((out==9)&en)?1:0; //产生进位信号 endmodule
20. 频率计锁存器模块
module latch_16(qo,din,load); output[15:0] qo;
17
input[15:0] din; input load; reg[15:0] qo;
always @(posedge load) begin qo=din; end endmodule
21. 交通灯控制器
/* 信号定义与说明: CLK: 为同步时钟;
EN: 使能信号,为 1的话,则控制器开始工作;
LAMPA: 控制A 方向四盏灯的亮灭;其中,LAMPA0~LAMPA3,分别控制A 方向的 左拐灯、绿灯、黄灯和红灯;
LAMPB: 控制 B方向四盏灯的亮灭;其中,LAMPB0 ~ LAMPB3,分别控制B方向的 左拐灯、绿灯、黄灯和红灯;
ACOUNT:用于A 方向灯的时间显示,8位,可驱动两个数码管; BCOUNT:用于B方向灯的时间显示,8位,可驱动两个数码管。 */ module traffic(CLK,EN,LAMPA,LAMPB,ACOUNT,BCOUNT); output[7:0] ACOUNT,BCOUNT; output[3:0] LAMPA,LAMPB; input CLK,EN; reg[7:0] numa,numb; reg tempa,tempb; reg[2:0] counta,countb;
reg[7:0] ared,ayellow,agreen,aleft,bred,byellow,bgreen,bleft; reg[3:0] LAMPA,LAMPB; always @(EN) if(!EN)
18
begin //设置各种灯的计数器的预置数 ared <=8'd55; //55秒 ayellow <=8'd5; //5秒 agreen <=8'd40; //40秒 aleft <=8'd15; //15秒 bred <=8'd65; //65秒 byellow <=8'd5; //5秒 bleft <=8'd15; //15秒 bgreen <=8'd30; //30秒 end
assign ACOUNT=numa; assign BCOUNT=numb;
always @(posedge CLK) //该进程控制A 方向的四种灯 begin if(EN) begin
if(!tempa) begin tempa<=1;
case(counta) //控制亮灯的顺序
0: begin numa<=agreen; LAMPA<=2; counta<=1; end 1: begin numa<=ayellow; LAMPA<=4; counta<=2; end 2: begin numa<=aleft; LAMPA<=1; counta<=3; end 3: begin numa<=ayellow; LAMPA<=4; counta<=4; end 4: begin numa<=ared; LAMPA<=8; counta<=0; end
19
default: LAMPA<=8; endcase end
else begin //倒计时 if(numa>1)
if(numa[3:0]==0)begin
numa[3:0]<=4'b1001; numa[7:4]<=numa[7:4]-1; end
else numa[3:0]<=numa[3:0]-1; if (numa==2) tempa<=0; end end
else begin
LAMPA<=4'b1000;
counta<=0; tempa<=0; end end
always @(posedge CLK) //该进程控制 B方向的四种灯 begin if (EN) begin if(!tempb) begin tempb<=1;
case (countb) //控制亮灯的顺序
0: begin numb<=bred; LAMPB<=8; countb<=1; end 1: begin numb<=bgreen; LAMPB<=2; countb<=2; end
20
2: begin numb<=byellow; LAMPB<=4; countb<=3; end 3: begin numb<=bleft; LAMPB<=1; countb<=4; end 4: begin numb<=byellow; LAMPB<=4; countb<=0; end default: LAMPB<=8; endcase end else
begin //倒计时 if(numb>1)
if(!numb[3:0]) begin numb[3:0]<=9;
numb[7:4]<=numb[7:4]-1; end
else numb[3:0]<=numb[3:0]-1; if(numb==2) tempb<=0; end end
else begin
LAMPB<=4'b1000; tempb<=0; countb<=0; end end endmodule
22. “梁祝”乐曲演奏电路
//信号定义与说明:
//clk_4Hz: 用于控制音长(节拍)的时钟频率; //clk_6MHz:用于产生各种音阶频率的基准频率;
//speaker: 用于激励扬声器的输出信号,本例中为方波信号;
21
//high, med, low:分别用于显示高音、中音和低音音符,各驱动一个数码管来显示。 module song(clk_6MHz,clk_4Hz,speaker,high,med,low); input clk_6MHz, clk_4Hz; output speaker;
output[3:0] high,med,low;
reg[3:0] high,med,low; reg[13:0] divider,origin; reg[7:0] counter; reg speaker; wire carry;
assign carry=(divider==16383); always @(posedge clk_6MHz)
begin if(carry) divider=origin; else divider=divider+1; end
always @(posedge carry) begin
speaker=~speaker; end
always @(posedge clk_4Hz) begin
case({high,med,low}) 'b000000000011: origin=7281; 'b000000000101: origin=8730; 'b000000000110: origin=9565; 'b000000000111: origin=10310; 'b000000010000: origin=107;
22
//2分频产生方波信号 //分频比预置 'b000000100000: origin=11272; 'b000000110000: origin=11831; 'b000001010000: origin=12556; 'b000001100000: origin=12974; 'b000100000000: origin=13516; 'b000000000000: origin=16383; endcase end
always @(posedge clk_4Hz) begin
if(counter==63) counter=0; else counter=counter+1; case(counter)
0: {high,med,low}='b000000000011; 1: {high,med,low}='b000000000011; 2: {high,med,low}='b000000000011; 3: {high,med,low}='b000000000011;
4: {high,med,low}='b000000000101; 5: {high,med,low}='b000000000101; 6: {high,med,low}='b000000000101;
7: {high,med,low}='b000000000110; 8: {high,med,low}='b000000010000; 9: {high,med,low}='b000000010000; 10: {high,med,low}='b000000010000;
11: {high,med,low}='b000000100000; 23
//计时,以实现循环演奏 //记谱 //低音“3” //持续 4个时钟节拍 //低音“5” //发 3个时钟节拍 //低音“6” //中音“1” //发 3个时钟节拍 //中音“2”
12: {high,med,low}='b000000000110; //低音“6” 13: {high,med,low}='b000000010000; 14: {high,med,low}='b000000000101; 15: {high,med,low}='b000000000101;
16: {high,med,low}='b000001010000; //中音“5” 17: {high,med,low}='b000001010000; //发 3个时钟节拍 18: {high,med,low}='b000001010000; 19: {high,med,low}='b000100000000; 20: {high,med,low}='b000001100000; 21: {high,med,low}='b000001010000; 22: {high,med,low}='b000000110000; 23: {high,med,low}='b000001010000; 24: {high,med,low}='b000000100000; 25: {high,med,low}='b000000100000; 26: {high,med,low}='b000000100000; 27: {high,med,low}='b000000100000; 28: {high,med,low}='b000000100000; 29: {high,med,low}='b000000100000; 30: {high,med,low}='b000000100000; 31: {high,med,low}='b000000100000; 32: {high,med,low}='b000000100000; 33: {high,med,low}='b000000100000; 34: {high,med,low}='b000000100000; 35: {high,med,low}='b000000110000; 36: {high,med,low}='b000000000111; 37: {high,med,low}='b000000000111;
24
//高音“1” //中音“2”
//持续 11个时钟节拍//中音“3” //低音“7”
38: {high,med,low}='b000000000110; //低音“6” 39: {high,med,low}='b000000000110;
40: {high,med,low}='b000000000101; //低音“5” 41: {high,med,low}='b000000000101; 42: {high,med,low}='b000000000101;
43: {high,med,low}='b000000000110; //低音“6” 44: {high,med,low}='b000000010000; 45: {high,med,low}='b000000010000;
46: {high,med,low}='b000000100000; 47: {high,med,low}='b000000100000;
48: {high,med,low}='b000000000011; 49: {high,med,low}='b000000000011;
50: {high,med,low}='b000000010000; 51: {high,med,low}='b000000010000; 52: {high,med,low}='b000000000110;
53: {high,med,low}='b000000000101; : {high,med,low}='b000000000110;
55: {high,med,low}='b000000010000; 56: {high,med,low}='b000000000101; 57: {high,med,low}='b000000000101; 钟节拍
58: {high,med,low}='b000000000101; 59: {high,med,low}='b000000000101; 60: {high,med,low}='b000000000101; 61: {high,med,low}='b000000000101; 62: {high,med,low}='b000000000101; 63: {high,med,low}='b000000000101;
25
//中音“1” //中音“2” //低音“3” //中音“1” //低音“5” //中音“1” //低音“5” //持续 8个时 endcase end endmodule
23. 自动售饮料机
/*信号定义:
clk: 时钟输入; reset: 为系统复位信号; half_dollar: 代表投入 5角硬币; one_dollar: 代表投入 1元硬币; half_out: 表示找零信号;
dispense: 表示机器售出一瓶饮料;
collect: 该信号用于提示投币者取走饮料。 */ module sell(one_dollar,half_dollar,
collect,half_out,dispense,reset,clk); parameter idle=0,one=2,half=1,two=3,three=4;
//idle,one,half,two,three为中间状态变量,代表投入币值的几种情况 input one_dollar,half_dollar,reset,clk; output collect,half_out,dispense; reg collect,half_out,dispense; reg[2:0] D;
always @(posedge clk) begin
if(reset) begin
dispense=0; collect=0; half_out=0; D=idle; end
26
case(D) idle:
if(half_dollar) D=half; else if(one_dollar) D=one; half:
if(half_dollar) D=one; else if(one_dollar) D=two; one:
if(half_dollar) D=two; else if(one_dollar) D=three; two:
if(half_dollar) D=three; else if(one_dollar) begin
dispense=1; //售出饮料 collect=1; D=idle; end three:
if(half_dollar) begin
dispense=1; //售出饮料
collect=1; D=idle; end
else if(one_dollar) begin
27
dispense=1; //售出饮料 collect=1; half_out=1; D=idle; end endcase end endmodule
28
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- huatuo3.com 版权所有 蜀ICP备2023022190号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务