Untitled

 avatar
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...