Untitled
unknown
plain_text
4 years ago
14 kB
9
Indexable
/*module clock_divider #(parameter n=27) (
input clk,
output clk_div);
reg [n-1:0] num = 0;
wire [n-1:0] num_next;
always @(posedge clk) begin
num = num_next;
end
assign num_next = num+1;
assign clk_div = num[n-1];
endmodule*/
module debounce(
input pb,
input clk,
output pb_debounced);
reg [3:0] shift_reg;
always @(posedge clk) begin
shift_reg[3:1] <= shift_reg[2:0];
shift_reg[0] <= pb;
end
assign pb_debounced = ((shift_reg == 4'b1111)?1'b1:1'b0);
endmodule
module onepulse(
input clk,
//input rst,
input pb_debounced,
output reg pb_1pulse);
// reg pb_1pulse_next;
reg pb_debounced_delay;
always @(posedge clk) begin
if(pb_debounced == 1'b1 & pb_debounced_delay == 1'b0)
pb_1pulse <= 1'b1;
else
pb_1pulse <= 1'b0;
pb_debounced_delay <= pb_debounced;
end
endmodule
module cntsecond(
input clk,
//input rst,
output reg clk_div
);
reg [26:0] counter = 0;
always @(posedge clk) begin
//if(rst) counter <= 50000000;
if(counter == 49999) counter <= 0;
else counter <= counter + 1;
end
always @(posedge clk) begin
clk_div <= (counter < 25000)?1'b0:1'b1;
end
endmodule
module lab5 (
input clk,
input rst,
input BTNL,//child
input BTNR,//adult
input BTNU,//ok
input BTND,//cancel
input BTNC,//student
output reg [15:0] LED,
output reg [3:0] DIGIT,
output reg [6:0] DISPLAY
);
//cnt second
wire clk_div;
//reg cnt_five_second_enable;
//reg duachi,duachi_next;//???
reg [15:0] cnt_flash,cnt_change,cnt_change_next,cnt_five_second;
cntsecond n1(.clk(clk),.clk_div(clk_div));
//clock divider
//debounce
wire BTNL_bounce,BTNR_bounce,BTNC_bounce,BTNU_bounce,BTND_bounce;
debounce d1(.pb(BTNL),.clk(clk_div),.pb_debounced(BTNL_bounce));
debounce d2(.pb(BTNR),.clk(clk_div),.pb_debounced(BTNR_bounce));
debounce d3(.pb(BTNC),.clk(clk_div),.pb_debounced(BTNC_bounce));
debounce d4(.pb(BTNU),.clk(clk_div),.pb_debounced(BTNU_bounce));
debounce d5(.pb(BTND),.clk(clk_div),.pb_debounced(BTND_bounce));
//one_pulse
wire BTNL_pulse,BTNR_pulse,BTNC_pulse,BTNU_pulse,BTND_pulse;
onepulse o1(.clk(clk_div),.pb_debounced(BTNL_bounce),.pb_1pulse(BTNL_pulse));
onepulse o2(.clk(clk_div),.pb_debounced(BTNR_bounce),.pb_1pulse(BTNR_pulse));
onepulse o3(.clk(clk_div),.pb_debounced(BTNC_bounce),.pb_1pulse(BTNC_pulse));
onepulse o4(.clk(clk_div),.pb_debounced(BTNU_bounce),.pb_1pulse(BTNU_pulse));
onepulse o5(.clk(clk_div),.pb_debounced(BTND_bounce),.pb_1pulse(BTND_pulse));
parameter [2:0]
IDLE = 3'b000,
TYPE = 3'b001,
AMOUNT = 3'b010,
PAYMENT = 3'b011,
RELEASE = 3'b100,
CHANGE = 3'b101,
RST = 3'b110;
reg [2:0] state,state_next;
reg [3:0] value,BCD_IDLE,BCD_ALPHABET;
//wire [3:0] BCD_IDLEE;
reg [15:0] led_next,led;
reg [1:0] first_in_IDLE,first_in_IDLE_next;
reg [3:0] cnt_BTNC,cnt_BTNL,cnt_BTNR,cnt_BTNU,cnt_BTND;
reg [3:0] price,amount,cnt_3second,BCD_IDLE_next,flash;//child:0,student:1,adult:2
reg [5:0] money,change,count_second_times,change_is_zero;
reg [5:0] change_next,change_is_zero_next,go_to_RELEASE,go_to_RELEASE_next;
//wire [5:0] mmoney;
//wire [3:0] aamount;
//cnt_second
always @(posedge clk_div or posedge rst) begin
if(rst) begin
cnt_five_second <= 0;
end
else begin
if(state == RELEASE) begin
if(cnt_five_second == 9999) cnt_five_second <= 0;
else cnt_five_second <= cnt_five_second + 1;
end
else cnt_five_second <= 0;
end
end
//state change
always @(posedge clk_div or posedge rst) begin
if(rst) begin
state <= IDLE;
//duachi <= 0;
end
else begin
state <= state_next;
// duachi <= duachi_next;
end
end
always @(*) begin
// duachi_next = 0;
case(state)
IDLE: begin
if(cnt_BTNL == 1) state_next = TYPE;
else if(cnt_BTNC == 1) state_next = TYPE;
else if(cnt_BTNR == 1) state_next = TYPE;
else state_next = IDLE;
end
TYPE: begin
if(cnt_BTNU == 1) state_next = AMOUNT;
else if(cnt_BTND == 1) begin
state_next = IDLE;
//duachi_next = 1;
end
else state_next = TYPE;
end
AMOUNT: begin
if(cnt_BTNU == 1) state_next = PAYMENT;
else if (cnt_BTND == 1) begin
state_next = IDLE;
//duachi_next = 1;
end
else state_next = AMOUNT;
end
PAYMENT: begin
if(money >= price*amount) begin
state_next = RELEASE;
// duachi_next = 1;
end
else if(cnt_BTND == 1) begin
state_next = CHANGE;
// duachi_next = 1;
end
else state_next = PAYMENT;
end
RELEASE: begin
if(cnt_five_second == 9999) begin
state_next = CHANGE;
//duachi_next = 1;
end
else state_next = RELEASE;
end
CHANGE: begin
if(change_is_zero == 1) begin
state_next = IDLE;
//duachi_next = 1;
end
else state_next = CHANGE;
end
default: state_next = IDLE;
endcase
end
//output led and clk_control
always @(posedge clk_div or posedge rst) begin
if(rst) begin
LED <= 16'b0000_0000_0000_0000;
cnt_flash <= 0;
end
else begin
if(state == IDLE || state == RELEASE) begin
if(cnt_flash == 1999) begin//2000-1
LED <= ~LED;
cnt_flash <= 0;
end
else begin
LED <= LED;
cnt_flash <= cnt_flash + 1;
end
end
else begin
LED <= 16'b0000_0000_0000_0000;
cnt_flash <= 0;
end
end
end
//assign LED = (rst == 0 &&(state == IDLE || state == RELEASE))?led:16'b0000_0000_0000_0000;
//in IDLE flashing 4-DIGIT
always @(posedge clk_div or posedge rst) begin
if(rst) BCD_IDLE <= 4'd10;
else if(state == IDLE || state == RELEASE) begin
if(cnt_flash == 1999) begin
if(BCD_IDLE == 4'd10) BCD_IDLE <= 4'd11;
else BCD_IDLE <= 4'd10;
end
else BCD_IDLE <= BCD_IDLE;
end
else BCD_IDLE <= 4'd10;
end
//assign BCD_IDLEE = (rst == 0 && flash == 0 && state == IDLE)?4'd11:BCD_IDLE;
//BTNL,BTNR,BTNC,BTNU,BTND press count
always @(posedge clk_div or posedge rst) begin
if(rst) begin
cnt_BTNL <= 0;
cnt_BTNR <= 0;
cnt_BTNC <= 0;
cnt_BTNU <= 0;
cnt_BTND <= 0;
end
else begin
if(state == state_next) begin//same as cnt_cycle
if(BTNL_pulse) cnt_BTNL <= cnt_BTNL + 1;
else if(BTNR_pulse) cnt_BTNR <= cnt_BTNR + 1;
else if(BTNC_pulse) cnt_BTNC <= cnt_BTNC + 1;
else if(BTNU_pulse) cnt_BTNU <= cnt_BTNU + 1;
else if(BTND_pulse) cnt_BTND <= cnt_BTND + 1;
else begin
cnt_BTNL <= cnt_BTNL;
cnt_BTNR <= cnt_BTNR;
cnt_BTNC <= cnt_BTNC;
cnt_BTNU <= cnt_BTNU;
cnt_BTND <= cnt_BTND;
end
end
else begin
cnt_BTNL <= 0;
cnt_BTNR <= 0;
cnt_BTNC <= 0;
cnt_BTNU <= 0;
cnt_BTND <= 0;
end
end
end
//set price
always @(posedge clk_div or posedge rst) begin
if(rst) begin
price <= 0;
BCD_ALPHABET <= 4'd0;
end
else begin
if(state == IDLE || state == TYPE) begin
if(BTNL_pulse) begin
//child
price <= 5;
BCD_ALPHABET <= 4'd12;
end
else if(BTNC_pulse) begin
//student
price <= 10;
BCD_ALPHABET <= 4'd13;
end
else if(BTNR_pulse) begin
//adult
price <= 15;
BCD_ALPHABET <= 4'd14;
end
else begin
price <= price;
BCD_ALPHABET <= BCD_ALPHABET;
end
end
else begin
price <= price;
BCD_ALPHABET <= BCD_ALPHABET;
end
end
end
//set amount
always @(posedge clk_div or posedge rst) begin
if(rst) amount <= 1;
else begin
if(state == AMOUNT) begin
if(BTNL_pulse) begin
if(amount == 1) amount <= amount;
else amount <= amount - 1;
end
else if(BTNR_pulse) begin
if(amount == 3) amount <= amount;
else amount <= amount + 1;
end
else amount <= amount;
end
else if(state == IDLE) amount <= 1;
else amount <= amount;
end
end
//assign aamount = amount;
//set money
always @(posedge clk_div or posedge rst) begin
if(rst) money <= 0;
else begin
if(state == PAYMENT) begin
if(BTNL_pulse) money <= money + 1;
else if(BTNC_pulse) money <= money + 5;
else if(BTNR_pulse) money <= money + 10;
else money <= money;
end
else if(state == IDLE) money <= 0;
else money <= money;
end
end
//assign mmoney = money;
always @(posedge clk_div or posedge rst) begin
if(rst) begin
change <= 0;
change_is_zero <= 0;
cnt_change <= 0;
end
else begin
change <= change_next;
change_is_zero <= change_is_zero_next;
cnt_change <= cnt_change_next;
end
end
always @(*) begin
//go_to_RELEASE_next = 0;
change_is_zero_next = 0;
if(state == PAYMENT || state == RELEASE) begin//clk_onesecond > clk_div_16,state may change then no in if(money >= price*amount)
if(money >= price*amount) begin
change_next = money-(price*amount);
//go_to_RELEASE_next = 1;
end
else change_next = money;
end
else if(state == CHANGE) begin
if(cnt_change == 1999) begin
cnt_change_next = 0;
if(change >= 5) change_next = change - 5;
else if(change == 0) begin
change_next = 0;
change_is_zero_next = 1;
end
else change_next = change - 1;
end
else begin
change_next = change;
cnt_change_next = cnt_change + 1;
end
end
else if(state == IDLE) begin
change_next = 0;
cnt_change_next = 0;
end
else change_next = change;
end
//4-digit
always @(posedge clk_div) begin
case(DIGIT)
4'b1110: begin
DIGIT = 4'b1101;
if(state == IDLE) value = BCD_IDLE;
else if(state == TYPE) value = price/10;
else if(state == AMOUNT) value = 4'd10;//all dark
else if(state == PAYMENT) value = (price*amount)/10;
else if(state == RELEASE) value = 4'd10;
else value = change / 10;
end
4'b1101: begin
DIGIT = 4'b1011;
if(state == IDLE) value = BCD_IDLE;
else if(state == TYPE) value = 4'd10;
else if(state == AMOUNT) value = 4'd10;//all dark
else if(state == PAYMENT) value = money%10;
else if(state == RELEASE) value = 4'd10;
else value = 4'd10;
end
4'b1011: begin
DIGIT = 4'b0111;
if(state == IDLE) value = BCD_IDLE;
else if(state == TYPE) value = BCD_ALPHABET;
else if(state == AMOUNT) value = BCD_ALPHABET;
else if(state == PAYMENT) value = money/10;
else if(state == RELEASE) value = BCD_ALPHABET;
else value = 4'd10;
end
4'b0111: begin
DIGIT = 4'b1110;
if(state == IDLE) value = BCD_IDLE;
else if(state == TYPE) value = price%10;
else if(state == AMOUNT) value = amount;
else if(state == PAYMENT) value = (price*amount)%10;
else if(state == RELEASE) value = amount;
else value = change % 10;
end
default: begin
DIGIT = 4'b0111;
value = 4'd10;
end
endcase
end
//7-segement
always @(*) begin
case(value)//GFE_DCBA
4'd0: DISPLAY = 7'b100_0000;
4'd1: DISPLAY = 7'b111_1001;
4'd2: DISPLAY = 7'b010_0100;
4'd3: DISPLAY = 7'b011_0000;
4'd4: DISPLAY = 7'b001_1001;
4'd5: DISPLAY = 7'b001_0010;
4'd6: DISPLAY = 7'b000_0010;
4'd7: DISPLAY = 7'b111_1000;
4'd8: DISPLAY = 7'b000_0000;
4'd9: DISPLAY = 7'b001_0000;
4'd10: DISPLAY = 7'b111_1111; //???t
4'd11: DISPLAY = 7'b011_1111;//IDLE
4'd12: DISPLAY = 7'b100_0110;//C
4'd13: DISPLAY = 7'b001_0010;//S
4'd14: DISPLAY = 7'b000_1000;//A
default:DISPLAY= 7'b111_1111;
endcase
end
endmodule Editor is loading...