加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSSRSS-巴斯仪表网
您当前的位置:首页 > 电子发烧 > EDA技术

Verilog电话计费器的代码

时间:2013-08-27  来源:123485.com  作者:9stone

/*信号定义:
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;  en
//取卡后对一些信号进行复位
 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


分享到:
来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
栏目导航->EDA技术
  • 电子应用基础
  • 电源技术
  • 无线传输技术
  • 信号处理
  • PCB设计
  • EDA技术
  • 单片机学习
  • 电子工具设备
  • 技术文章
  • 精彩拆解欣赏
  • 推荐资讯
    使用普通运放的仪表放大器
    使用普通运放的仪表放
    3V与5V混合系统中逻辑器接口问题
    3V与5V混合系统中逻辑
    数字PID控制及其改进算法的应用
    数字PID控制及其改进
    恶劣环境下的高性价比AD信号处理数据采集系统
    恶劣环境下的高性价比
    栏目更新
    栏目热门