功能
- 单次计价:输入物品的重量、单价,显示物品的总价(=重量*单价)。
- 累计计价:
- 第一次按下累计按键,记住当前物品的总价(当前物品记为物品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 对应的键置零才能继续改变输入的重量和单价,否则次数会变化
此外,由于没用消抖开关可能出现多次加和的现象,务必小心(抱歉)