Untitled
unknown
plain_text
2 years ago
12 kB
2
Indexable
Never
module clock_divider #(parameter n = 25)( input clk, output clk_div ); reg [n-1:0] num = 0; wire[n-1:0] next_num; always @(posedge clk) begin num <= next_num; end assign next_num = num + 1; assign clk_div = num[n-1]; endmodule module lab3_2 ( input clk, input rst, input en, input speed, input freeze, output reg [15:0] led ); wire clk24; wire clk27; reg current_clk; reg [3:0]counter_car, next_counter_car; reg [3:0]counter_motor, next_counter_motor; reg [2:0] state, next_state; reg [15:0] car_pos, next_car_pos; reg [15:0] motor_pos, next_motor_pos; reg [2:0] car_score, next_car_score; reg [2:0] motor_score, next_motor_score; reg turbo_times, next_turbo_times; reg turbo_on; reg [2:0]turbo_counter, next_turbo_counter; integer i; clock_divider #( .n(24) ) clkdiv24 ( .clk(clk), .clk_div(clk24) ); clock_divider #( .n(27) ) clkdiv27 ( .clk(clk), .clk_div(clk27) ); parameter ALL_INIT = 3'd0; parameter ROUND_INIT = 3'd1; parameter RACING = 3'd2; parameter ROUND_FINISH = 3'd3; parameter CAR_WIN = 3'd4; parameter MOTOR_WIN = 3'd5; integer i; // state always@(posedge clk24, posedge rst) begin if(rst) begin state <= ALL_INIT; end else begin state <= next_state; end end always@(*) begin case(state) ALL_INIT:begin next_state = ROUND_INIT; end ROUND_INIT:begin next_state = RACING; end RACING:begin if(led[2] == 1) begin next_state = ROUND_FINISH; end else begin next_state = RACING; end end ROUND_FINISH:begin if(motor_score == 4) begin next_state = MOTOR_WIN; end else if(car_score == 4) begin next_state = CAR_WIN; end else begin next_state = ROUND_INIT; end end CAR_WIN:begin next_state = ALL_INIT; end MOTOR_WIN:begin next_state = ALL_INIT; end endcase end //turbo control always@(*) begin if(turbo_on == 1) begin current_clk = clk24; end else begin current_clk = clk27; end end always@(*)begin if(rst)begin turbo_on = 0; end else begin case(state) RACING:begin if((speed == 1 && turbo_times == 0) || (turbo_counter > 0 && turbo_counter < 5))begin turbo_on = 1; end end default: turbo_on = 0; endcase end end always@(current_clk) begin if(rst) begin turbo_counter <= 0; turbo_times <= 0; end else begin turbo_counter <= next_turbo_counter; turbo_times <= next_turbo_times; end end always@(*)begin case(state) ROUND_INIT:begin next_turbo_counter = 0; next_turbo_times = 0; end RACING:begin if(turbo_on == 1)begin next_turbo_counter = turbo_counter + 1; next_turbo_times = 1; end else begin next_turbo_counter = turbo_counter; next_turbo_times = turbo_times; end end default:begin next_turbo_counter = 0; next_turbo_times = 0; end endcase end //car position led always@(posedge current_clk, posedge rst) begin if(rst) begin for(i = 0; i < 16; i = i+1) begin car_pos[i] <= 0; end end else begin car_pos <= next_car_pos; end end always@(*) begin case(state) ALL_INIT:begin for(i = 0; i < 16; i = i+1) begin next_car_pos[i] = 0; end next_car_pos[13] = 1; next_car_pos[12] = 1; end ROUND_INIT: begin for(i = 0; i < 14; i = i+1) begin next_car_pos[i] = 0; end next_car_pos[13] = 1; next_car_pos[12] = 1; end RACING: begin for(i = 0; i < 14; i = i+1) begin next_car_pos[i] <= 0; end next_car_pos[counter_car] = 1; next_car_pos[counter_car - 1] = 1; end ROUND_FINISH:begin case(car_score) 3'd0:begin next_car_pos[15] = 0; next_car_pos[14] = 0; end 3'd1:begin next_car_pos[15] = 0; next_car_pos[14] = 1; end 3'd2:begin next_car_pos[15] = 1; next_car_pos[14] = 0; end 3'd3:begin next_car_pos[15] = 1; next_car_pos[14] = 1; end 3'd4:begin next_car_pos[15] = 1; next_car_pos[14] = 1; end default:begin end endcase end CAR_WIN:begin for(i = 2; i < 16; i = i+1) begin next_car_pos[i] = 1; end next_car_pos[0] = 0; next_car_pos[1] = 0; end MOTOR_WIN:begin for(i = 0; i < 16; i = i+1) begin next_car_pos[i] = 0; end end endcase end //car_score always@(posedge clk24, posedge rst)begin if(rst) begin car_score <= 0; end else begin car_score <= next_car_score; end end always@(*) begin case(state) ALL_INIT:begin next_car_score = 0; end ROUND_INIT:begin next_car_score = 0; end ROUND_FINISH:begin if(car_pos[2] == 1 && motor_pos[2] == 0)begin next_car_score = car_score + 1; end else begin next_car_score = car_score; end end endcase end //counter_car always@(*) begin if(rst) begin counter_car = 4'd13; end else begin counter_car = next_counter_car; end end always@(posedge current_clk)begin case(state) ROUND_INIT:begin next_counter_car <= 0; end RACING:begin if(en ==1 )begin next_counter_car <= counter_car + 1; end else begin next_counter_car <= counter_car; end end default: next_counter_car <= counter_car; endcase end /////////////////////////////////////////////////////////////////////// //motor position led always@(posedge clk24, posedge rst) begin if(rst) begin for(i = 0; i < 16; i = i+1) begin motor_pos[i] <= 0; end end else begin motor_pos <= next_motor_pos; end end always@(*) begin case(state) ALL_INIT:begin for(i = 0; i < 16; i = i+1) begin next_motor_pos[i] = 0; end next_motor_pos[10] = 1; end ROUND_INIT: begin for(i = 2; i < 16; i = i+1) begin next_motor_pos[i] = 0; end next_motor_pos[10] = 1; end RACING: begin for(i = 2; i < 16; i = i+1) begin next_motor_pos[i] <= 0; end next_motor_pos[counter_motor] = 1; next_motor_pos[counter_motor - 1] = 1; end ROUND_FINISH:begin case(motor_score) 3'd0:begin next_motor_pos[1] = 0; next_motor_pos[0] = 0; end 3'd1:begin next_motor_pos[1] = 0; next_motor_pos[0] = 1; end 3'd2:begin next_motor_pos[1] = 1; next_motor_pos[0] = 0; end 3'd3:begin next_motor_pos[1] = 1; next_motor_pos[0] = 1; end 3'd4:begin next_motor_pos[1] = 1; next_motor_pos[0] = 1; end default:begin end endcase end CAR_WIN:begin for(i = 0; i < 16; i = i+1) begin next_motor_pos[i] = 0; end end MOTOR_WIN:begin for(i = 0; i < 14; i = i+1) begin next_motor_pos[i] = 1; end next_motor_pos[15] = 0; next_motor_pos[14] = 0; end endcase end //motor_score always@(posedge clk24, posedge rst)begin if(rst) begin motor_score <= 0; end else begin motor_score <= next_motor_score; end end always@(*) begin case(state) ALL_INIT:begin next_motor_score = 0; end ROUND_INIT:begin next_motor_score = 0; end ROUND_FINISH:begin if(motor_pos[2] == 1)begin next_motor_score = motor_score + 1; end else begin next_motor_score = motor_score; end end endcase end //counter_motor always@(*) begin if(rst) begin counter_motor = 4'd13; end else begin counter_motor = next_counter_motor; end end always@(posedge clk27)begin case(state) ROUND_INIT:begin next_counter_motor <= 0; end RACING:begin if(freeze == 1) begin next_counter_motor <= counter_motor; end else if(en ==1 )begin next_counter_motor <= counter_motor + 1; end else begin next_counter_motor <= counter_motor; end end default: next_counter_motor <= counter_motor; endcase end //output always@(clk24) begin led <= car_pos | motor_pos; end endmodule