Verilog 电子秤设计
作者:互联网
能跑就行系列。。。
功能
- 单次计价:输入物品的重量、单价,显示物品的总价(=重量*单价)。
- 累计计价:
- 第一次按下累计按键,记住当前物品的总价(当前物品记为物品1),数码管依次显示: AC 次数 应付总价
- 继续输入物品2的重量、单价,显示物品2的总价。按下累计按键,将本次物品2的总价累加进之前的用户应付总价中,数码管显示:
AC 次数 总价
依次购买物品3、4……,每个物品后都通过累计按键将本次物品总价累计到应付总价中
- 退出累计状态:按下清除累计按键,恢复普通状态。
topmodule 顶层模块
module top_module(
input clk100mhz,
input clr,
input Go,
input [3:0]weight,
input [3:0]price,
output [3:0]pos1,
output [3:0]pos2,
output [7:0]seg1,
output [7:0]seg2
);
wire clk190hz, clk3hz;
wire [15:0]dataBus1;
wire [15:0]dataBus2;
clkDiv U1(clk100mhz, clk190hz, clk3hz);
GPU U2(.clk3hz(clk100mhz),.clr(clr),.Go(Go),.weight(weight),.price(price),.dataBus1(dataBus1),.dataBus2(dataBus2));
segMsgout U3(clk190hz,dataBus1, pos1, seg1); //前四位显示数码管
segMsgout U4(clk190hz,dataBus2, pos2, seg2); //后四位显示数码管
endmodule
clkDiv 分频模块
module clkDiv(
input clk100mhz,
output clk190hz,
output clk3hz
);
reg [25:0]count=0;
assign clk190hz=count[18];
assign clk3hz=count[25];
always@(posedge clk100mhz)
count<=count+1;
endmodule
GPU 模块
module GPU(
input clk3hz,
input clr,
input Go,
input [3:0]weight,
input [3:0]price,
output reg [15:0]dataBus1,
output reg [15:0]dataBus2,
output reg [15:0]total,
output reg [7:0]count
);
parameter S0=1'b0,S1=1'b1;
reg [7:0]weight_t;
reg [7:0]price_t;
reg [31:0]msgArray;
reg present_state;
reg next_state;
wire [3:0]weight_h;
wire [3:0]weight_l;
wire [3:0]price_h;
wire [3:0]price_l;
reg [15:0]multiple;
reg [3:0]total_1;
reg [3:0]total_2;
reg [3:0]total_3;
reg [3:0]total_4;
reg tip; //中间状态限制量
initial
begin
total[15:0]=0; //总价
count[7:0]=0; //输入次数
msgArray[31:0]=0;
present_state=S0;
next_state=S0;
//中间过程量
multiple[15:0]=0;
total_1[3:0]=4'b0000;
total_2[3:0]=4'b0000;
total_3[3:0]=4'b0000;
total_4[3:0]=4'b0000;
tip=0;
end
always@(posedge clk3hz or posedge clr)
begin
if(clr) //清零功能
begin
dataBus1[15:0]<=16'b0000_0000_0000_0000;
dataBus2[15:0]<=16'b0000_0000_0000_0000;
end
else
begin
if(present_state==S1) //总价
begin
dataBus1[15:0] <={8'b1010_1100 ,count[7:0]};
dataBus2[15:0] <= total[15:0];
end
else if(present_state==S0) //加和
begin
dataBus1[15:0]<=msgArray[31:16];
dataBus2[15:0]<=msgArray[15:0];
end
end
end
always@(posedge clk3hz or posedge clr) //数值变换
begin
if(clr)
begin
next_state<=S0;
msgArray[31:0]<= 32'b0000_0000_0000_0000_0000_0000_0000_0000;
count[7:0]<=8'b0000_0000;
total_1[3:0]<=4'b0000;
total_2[3:0]<=4'b0000;
total_3[3:0]<=4'b0000;
total_4[3:0]<=4'b0000;
tip<=0;
end
else
begin
if(Go) //进入总和显示状态
next_state<=S1;
if(present_state==S1)
begin
if(msgArray[31:16]!={weight_t[7:0],price_t[7:0]})
begin
next_state<=S0;
tip<=0;
end
end
else if(present_state==S0)
begin
if(next_state==S0)
begin
msgArray[31:16]<={weight_t[7:0],price_t[7:0]};
msgArray[15:0]<=multiple[15:0];
end
else if(next_state==S1)
begin
if(tip==0)
begin
count[7:0]<=count[7:0]+1;
total_1[3:0]<=total_1[3:0]+multiple[3:0];
total_2[3:0]<=total_2[3:0]+multiple[7:4];
total_3[3:0]<=total_3[3:0]+multiple[11:8];
total_4[3:0]<=total_4[3:0]+multiple[15:12];
tip<=1;
end
end
end
if(total_1[3:0]>=4'b1010)
begin
total_2[3:0]<=total_2[3:0]+4'b0001;
total_1[3:0]<=total_1[3:0]-4'b1010;
end
// else total_1[3:0]<=total_1[3:0];
if(total_2[3:0]>=4'b1010)
begin
total_3[3:0]<=total_3[3:0]+4'b0001;
total_2[3:0]<=total_2[3:0]-4'b1010;
end
// else total_2[3:0]<=total_2[3:0];
if(total_3[3:0]>=4'b1010)
begin
total_4[3:0]<=total_4[3:0]+4'b0001;
total_3[3:0]<=total_3[3:0]-4'b1010;
end
// else total_3[3:0]<=total_3[3:0];
end
end
always@(posedge clk3hz) //单次总价进制转换
begin
weight_t[7:0]<={weight_h[3:0],weight_l[3:0]};
price_t[7:0]<={price_h[3:0], price_l[3:0]};
multiple[15:12]<={price[3:0]*weight[3:0]/1000};
multiple[11:8]<={price[3:0]*weight[3:0]/100%10};
multiple[7:4]<={price[3:0]*weight[3:0]/10%10};
multiple[3:0]<={price[3:0]*weight[3:0]%10};
end
always@(posedge clk3hz or posedge clr) //状态转移
begin
if(clr)
begin
present_state<= S0;
total[15:0]<=16'b0000_0000_0000_0000;
end
else
begin
total[15:0]<={total_4[3:0],total_3[3:0],total_2[3:0],total_1[3:0]};
if(present_state==0&&next_state==1)
begin
if(tip==1)
present_state<=next_state;
else
present_state<=present_state;
end
else
present_state<=next_state;
end
end
//进制转换
assign weight_h[3:0]=(weight[3:0]>=10)?4'b0001:4'b0000;
assign weight_l[3:0]=(weight[3:0]>=10)?weight[3:0]-4'b1010:weight[3:0];
assign price_h[3:0]=(price[3:0]>=10)?4'b0001:4'b0000;
assign price_l[3:0]=(price[3:0]>=10)?price[3:0]-4'b1010:price[3:0];
endmodule
segMsgout 数码管显示模块
module segMsgout(
input clk190hz,
input [15:0]dataBus,
output reg [3:0] pos,
output reg [7:0] seg
);
reg [1:0] posC;
reg [3:0] dataP;
always @(posedge clk190hz )begin
case(posC)
0: begin
pos<=4'b1000;
dataP<=dataBus[15:12];
end
1:begin
pos <=4'b0100;
dataP <= dataBus[11:8];
end
2:begin
pos <=4'b0010;
dataP <= dataBus[7:4];
end
3:begin
pos <=4'b0001;
dataP <= dataBus[3:0];
end
endcase
posC = posC + 2'b01;
end
always @(dataP)
case(dataP)
4'b0000:seg=8'b0011_1111;
4'b0001:seg=8'b0000_0110;
4'b0010:seg=8'b0101_1011;
4'b0011:seg=8'b0100_1111;
4'b0100:seg=8'b0110_0110;
4'b0101:seg=8'b0110_1101;
4'b0110:seg=8'b0111_1101;
4'b0111:seg=8'b0000_0111;
4'b1000:seg=8'b0111_1111;
4'b1001:seg=8'b0110_1111;
4'b1010:seg=8'b0111_0111; //A
4'b1100:seg=8'b0011_1001; //C
default:seg=8'b0000_1000;
endcase
endmodule
仿真模块:
module top_module_tb();
reg clk100mhz;
reg clr;
reg Go;
reg [3:0]weight;
reg [3:0]price;
wire [15:0]total;
wire [7:0]count;
wire [15:0]dataBus1;
wire [15:0]dataBus2;
GPU U2(.clk3hz(clk100mhz),.clr(clr),.Go(Go),
.weight(weight),.price(price),.dataBus1(dataBus1),.dataBus2(dataBus2),
.count(count),.total(total));
initial
begin
clk100mhz = 1'b0;
clr=1'b0;
Go=1'b0;
weight[3:0]=0;
price[3:0]=0;
#50 weight[3:0]=4'b1001;
price[3:0]=4'b0001;
#100 Go=1'b1;
#50 weight[3:0]=4'b0010;
price[3:0]=4'b0010;
Go=1'b0;
#100 Go=1'b1;
#50 weight[3:0]=4'b1110;
price[3:0]=4'b0011;
Go=1'b0;
#100 Go=1'b1;
#50 weight[3:0]=4'b0110;
price[3:0]=4'b1011;
Go=1'b0;
#100 Go=1'b1;
#50 weight[3:0]=4'b0011;
price[3:0]=4'b1010;
Go=1'b0;
#100 clr=1'b1;
end
always #5 clk100mhz<= ~clk100mhz;
endmodule
管脚约束
set_property PACKAGE_PIN G2 [get_ports {pos1[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pos1[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pos1[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pos1[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pos1[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pos2[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pos2[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pos2[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pos2[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {price[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {price[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {price[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {price[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg2[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg2[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg2[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg2[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg2[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg2[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg2[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg2[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {weight[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {weight[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {weight[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {weight[0]}]
set_property PACKAGE_PIN C2 [get_ports {pos1[2]}]
set_property PACKAGE_PIN C1 [get_ports {pos1[1]}]
set_property PACKAGE_PIN H1 [get_ports {pos1[0]}]
set_property PACKAGE_PIN G1 [get_ports {pos2[3]}]
set_property PACKAGE_PIN F1 [get_ports {pos2[2]}]
set_property PACKAGE_PIN E1 [get_ports {pos2[1]}]
set_property PACKAGE_PIN G6 [get_ports {pos2[0]}]
set_property PACKAGE_PIN R2 [get_ports {price[3]}]
set_property PACKAGE_PIN M4 [get_ports {price[2]}]
set_property PACKAGE_PIN N4 [get_ports {price[1]}]
set_property PACKAGE_PIN R1 [get_ports {price[0]}]
set_property PACKAGE_PIN P5 [get_ports {weight[3]}]
set_property PACKAGE_PIN P4 [get_ports {weight[2]}]
set_property PACKAGE_PIN P3 [get_ports {weight[1]}]
set_property PACKAGE_PIN P2 [get_ports {weight[0]}]
set_property PACKAGE_PIN D5 [get_ports {seg1[7]}]
set_property PACKAGE_PIN B2 [get_ports {seg1[6]}]
set_property PACKAGE_PIN B3 [get_ports {seg1[5]}]
set_property PACKAGE_PIN A1 [get_ports {seg1[4]}]
set_property PACKAGE_PIN B1 [get_ports {seg1[3]}]
set_property PACKAGE_PIN A3 [get_ports {seg1[2]}]
set_property PACKAGE_PIN A4 [get_ports {seg1[1]}]
set_property PACKAGE_PIN B4 [get_ports {seg1[0]}]
set_property PACKAGE_PIN H2 [get_ports {seg2[7]}]
set_property PACKAGE_PIN D2 [get_ports {seg2[6]}]
set_property PACKAGE_PIN E2 [get_ports {seg2[5]}]
set_property PACKAGE_PIN F3 [get_ports {seg2[4]}]
set_property PACKAGE_PIN F4 [get_ports {seg2[3]}]
set_property PACKAGE_PIN D3 [get_ports {seg2[2]}]
set_property PACKAGE_PIN E3 [get_ports {seg2[1]}]
set_property PACKAGE_PIN D4 [get_ports {seg2[0]}]
set_property PACKAGE_PIN P17 [get_ports clk100mhz]
set_property PACKAGE_PIN T5 [get_ports clr]
set_property PACKAGE_PIN U3 [get_ports Go]
set_property IOSTANDARD LVCMOS33 [get_ports clk100mhz]
set_property IOSTANDARD LVCMOS33 [get_ports clr]
set_property IOSTANDARD LVCMOS33 [get_ports Go]
操作提示:
每次加完价都必须把 Go 对应的键置零才能继续改变输入的重量和单价,否则次数会变化
此外,由于没用消抖开关可能出现多次加和的现象,务必小心(抱歉)
标签:set,PIN,get,电子秤,LVCMOS33,Verilog,设计,property,ports 来源: https://blog.csdn.net/lsdqyz/article/details/122162873