看见以前有人在【设计交流 】里发过但是不知为什么后来没了。现在碰巧手上有献给大家。
pdf格式说明文档 王金明:《Verilog HDL 程序设计教程》 共83页。
为方便大家了解现节选几例。
【例3.1】4 位全加器 『基础啊!』
module adder4(cout,sum,ina,inb,cin);
output[3:0] sum;
output cout;
input[3:0] ina,inb;
input cin;
assign {cout,sum}=ina+inb+cin;
endmodule
【例3.5】“与-或-非”门电路
module AOI(A,B,C,D,F); //模块名为AOI(端口列表A,B,C,D,F)
input A,B,C,D; //模块的输入端口为A,B,C,D
output F; //模块的输出端口为F
wire A,B,C,D,F; //定义信号的数据类型
assign F= ~((A&B)|(C&D)); //逻辑功能描述
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
【例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
【例11.9】电话计费器程序
/*信号定义:
clk: 时钟信号,本例中其频率值为1Hz;
decide: 电话局反馈回来的信号,代表话务种类,“01”表示市话,“10”表示
长话,“11”表示特话;
dispmoney: 用来显示卡内余额,其单位为角,这里假定能显示的最大数额为50 元
(500 角);
disptime: 显示本次通话的时长;
write,read: 当write 信号下降沿到来时写卡,当话卡插入,read 信号变高时读卡;
warn: 余额过少时的告警信号。本例中,当打市话时,余额少于3 角,打长
话时,余额少于6 角,即会产生告警信号;
cut: 当告警时间过长时自动切断通话信号。 */
module account(state,clk,card,decide,disptime,dispmoney,
write,read,warn,cut);
output write,read,warn,cut;
input state,clk,card;
input[2:1] decide;
output[10:0] dispmoney;
output[8:0] disptime;
reg[10:0] money;
reg[8:0] dtime;
reg warn,cut,write,t1m; //t1m 为分时钟
reg set,reset_ena;
integer num1,temp;
assign dispmoney=card?money:0;
assign disptime=dtime;
assign read=card?1:0;
//产生分时钟
always @(posedge clk)
begin
if (num1==59) begin num1<=0; t1m<=1; end
else begin
if(state) num1<=num1+1;
else num1<=0; t1m<=0;
end
end
always @(negedge clk) //该进程完成电话计费功能
begin
if(!set)
begin money<=11'h500; set<=1; end
if(card&state)
if(t1m)
case({state,decide})
3'b101: if(money<3)
begin warn<=1; write<=0; reset_ena<=1; end
else
begin //市话计费
if(money[3:0]<4'b0011)
begin
money[3:0]<=money[3:0]+7;
if(money[7:4]!=0)
money[7:4]<=money[7:4]-1;
else
begin money[7:4]<=9; money[10:8]<=money[10:8]-1; end
end
else money[3:0]<=money[3:0]-3; write<=1;
//市话通话计时
if(dtime[3:0]==9)
begin
dtime[3:0]<=0;
if(dtime[7:4]==9)
begin dtime[7:4]<=0; dtime[8]<=dtime[8]+1; end
else dtime[7:4]<=dtime[7:4]+1;
end
else
begin
dtime[3:0]<=dtime[3:0]+1; warn<=0; reset_ena<=0;
end
end
3'b110: if(money<6)
begin warn<=1; write<=0; reset_ena<=1; end
else begin
//通话计时
if(dtime[3:0]==9)
begin
dtime[3:0]<=0; if(dtime[7:4]==9)
begin dtime[7:4]<=0; dtime[8]<=dtime[8]+1; end
else dtime[7:4]<=dtime[7:4]+1;
end
else dtime[3:0]<=dtime[3:0]+1;
//长话计费
if(money[3:0]<4'b0110)
begin
money[3:0]<=money[3:0]+4;
if(!money[7:4])
begin money[7:4]<=9; money[10:8]<=money[10:8]-1; end
else money[7:4]<=money[7:4]-1;
end
else money[3:0]<=money[3:0]-6;
write<=1; reset_ena<=0; warn<=0;
end
endcase
else write<=0;
else begin dtime<=0; warn<=0; write<=0; reset_ena<=0; end
//取卡后对一些信号进行复位
end
always @(posedge clk) //该进程在告警时间过长的情况下切断本次通话
begin
if(warn) temp<=temp+1;
else temp<=0;
if(temp==15)
begin cut<=1; temp<=0; end
if(!card||!reset_ena)
begin
cut<=0; //复位cut 信号
temp<=0;
end
end
endmodule |