// Next state logic always_comb begin case (state) IDLE: begin if (edge_detected_coin5) next_state = PAID5; else if (edge_detected_coin10) next_state = PAID10; else next_state = state; end PAID5: begin if (edge_detected_coin5) next_state = PAID10; else if (edge_detected_coin10) next_state = PAID15; else next_state = state; end PAID10: begin if (edge_detected_coin5) next_state = PAID15; else if (edge_detected_coin10) next_state = PAID20; else next_state = state; end PAID15: begin // 保持住现在的状态 if(timer_done) next_state = WAIT_RESET; else next_state = state; end PAID20: begin // 保持住现在的状态 if(timer_done) next_state = WAIT_RESET; else next_state = state; end WAIT_RESET: next_state = IDLE; default: next_state = IDLE; endcase end
state_t state, next_state; logic [7:0] total_paid; logic [7:0] change_amount; logic timer_done; logic enable_1ms; logic edge_detected_coin5, edge_detected_coin10; timer_10s timer_10s_inst( .sys_clk(sys_clk), .sys_rst_n(sys_rst_n), .start(state == PAID15 || state == PAID20), .done(timer_done) ); // Instantiate timer module for edge detection and 1ms enable signal timer_module timer_module_inst( .sys_clk(sys_clk), .sys_rst_n(sys_rst_n), .coin5(coin5), .coin10(coin10), .enable_1ms(enable_1ms), .edge_detected_coin5(edge_detected_coin5), .edge_detected_coin10(edge_detected_coin10) ); // Output logic assign price = (state == WAIT_RESET) ? 8'd0 : total_paid; // Price represents the total paid amount assign change = (state == WAIT_RESET) ? 8'd0 : change_amount; assign open = (state == PAID15 || state == PAID20); assign led = (state == PAID15 || state == PAID20); // LED on for 10 seconds after successful purchase
// State transition always_ff @(posedge sys_clk) begin if (~sys_rst_n) state <= IDLE; else state <= next_state; //次态变为现态 end
// Next state logic always_comb begin case (state) IDLE: begin if (edge_detected_coin5) next_state = PAID5; else if (edge_detected_coin10) next_state = PAID10; else next_state = state; end PAID5: begin if (edge_detected_coin5) next_state = PAID10; else if (edge_detected_coin10) next_state = PAID15; else next_state = state; end PAID10: begin if (edge_detected_coin5) next_state = PAID15; else if (edge_detected_coin10) next_state = PAID20; else next_state = state; end PAID15: begin // 保持住现在的状态 if(timer_done) next_state = WAIT_RESET; else next_state = state; end PAID20: begin // 保持住现在的状态 if(timer_done) next_state = WAIT_RESET; else next_state = state; end WAIT_RESET: next_state = IDLE; default: next_state = IDLE; endcase end
// Total paid logic always_ff @(posedge sys_clk) begin if (~sys_rst_n) total_paid <= 8'd0; else if(state == WAIT_RESET) total_paid <= 8'd0; else if (edge_detected_coin5) total_paid <= total_paid + 8'd5; else if (edge_detected_coin10) total_paid <= total_paid + 8'd10; end // Change calculation logic always_ff @(posedge sys_clk) begin if (~sys_rst_n) change_amount <= 8'd0; else if (state == PAID20) change_amount <= 8'd5; else change_amount <= 8'd0; end endmodule
// Scan state machine always_ff @(posedge sys_clk) begin if (~sys_rst_n) scan_state <= 2'd0; //为了加快仿真速度,这里调整为50个时钟周期(1/10 时间) else if (enable_1ms) // 25MHz clock / 1KHz = 25000 如果计数器 counter 达到24999(即1ms),则将 scan_state 加1。 scan_state <= (scan_state == 2'd3) ? 2'd0 : scan_state + 2'd1;//该变量用于跟踪当前正在扫描的数码管,2'd0到2'd3分别表示4个数码管。 end
// Digit and anode control always_comb begin case (scan_state) 2'd0: begin digit = paid_bcd[3:0]; an = 4'b0001; // Enable AN0 end 2'd1: begin digit = paid_bcd[7:4]; an = 4'b0010; // Enable AN1 end 2'd2: begin digit = change_bcd[3:0]; an = 4'b0100; // Enable AN2 end 2'd3: begin digit = change_bcd[7:4]; an = 4'b1000; // Enable AN3 end default: begin digit = 4'd0; an = 4'b0000; end endcase end
// Parameters for simulation localparam integer SIMULATION_CLK_PERIOD = 4; // 4ns for 250MHz clock to speed up simulation localparam integer SIMULATION_WAIT_TIME = 20; // 20ns for each test case observation
// Parameters for simulation localparam integer SIMULATION_CLK_PERIOD = 4; // 4ns for 250MHz clock to speed up simulation localparam integer SIMULATION_WAIT_TIME = 20; // 20ns for each test case observation
// Test case 4: Insert 5 cents, then another 5 cents, and then 10 cents to reach 20 cents #(SIMULATION_WAIT_TIME); coin5 = 1; #(SIMULATION_WAIT_TIME); coin5 = 0; #(SIMULATION_WAIT_TIME * 2); // Short wait to observe state change
// Insert second 5 cents #(SIMULATION_WAIT_TIME); coin5 = 1; #(SIMULATION_WAIT_TIME); coin5 = 0; #(SIMULATION_WAIT_TIME * 2); // Short wait to observe state change
// Insert 10 cents #(SIMULATION_WAIT_TIME); coin10 = 1; #(SIMULATION_WAIT_TIME); coin10 = 0; #(SIMULATION_WAIT_TIME * 2); // Short wait to observe state change
// Parameters for simulation localparam integer SIMULATION_CLK_PERIOD = 4; // 1ns for 1GHz clock to speed up simulation localparam integer SIMULATION_WAIT_TIME = 20; // 10ns for each test case observation