Verilog电话计费器的代码
2013-01-15
标签:

/*信号定义:

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;

assigndispmoney=card?money:0;

assigndisptime=dtime;

assignread=card?1:0;

always @(posedge clk)

begin

if (num1==59)beginnum1<=0;t1m<=1;end

elsebegin

if(state)num1<=num1+1;

elsenum1<=0;t1m<=0;

end

end

always @(negedge clk)//该进程完成电话计费功能

begin

if(!set)

beginmoney<=11'h500;set<=1;end

if(card&state)

if(t1m)

case({state,decide})

3'b101:if(money<3)

beginwarn<=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

beginmoney[7:4]<=9;money[10:8]<=money[10:8]-1;end

end

elsemoney[3:0]<=money[3:0]-3;write<=1;

//市话通话计时

if(dtime[3:0]==9)

begin

dtime[3:0]<=0;

if(dtime[7:4]==9)

begindtime[7:4]<=0;dtime[8]<=dtime[8]+1;end

elsedtime[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)

beginwarn<=1;write<=0;reset_ena<=1;end

else begin

//通话计时

if(dtime[3:0]==9)

begin

dtime[3:0]<=0;if(dtime[7:4]==9)

begindtime[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])

beginmoney[7:4]<=9;money[10:8]<=money[10:8]-1;end

elsemoney[7:4]<=money[7:4]-1;

end

elsemoney[3:0]<=money[3:0]-6;

write<=1;reset_ena<=0;warn<=0;

end

endcase

else write<=0;

elsebegindtime<=0;warn<=0;write<=0;reset_ena<=0;en

//取卡后对一些信号进行复位

end

always @(posedge clk)//该进程在告警时间过长的情况下切断本次通话

begin

if(warn)temp<=temp+1;

else temp<=0;

if(temp==15)

begincut<=1;temp<=0;end

if(!card||!reset_ena)

begin

cut<=0;//复位cut信号

temp<=0;

end

end

endmodule

可能会用到的工具/仪表
相关文章
推荐文章
热门文章
章节目录
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号