Untitled
unknown
plain_text
4 years ago
14 kB
4
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...