12.21 Торговый автомат, один предмет, несколько предметов

торговый автомат 

если наивный метод

 Одна из идей состоит в том, чтобы использовать регистр cnt для записи существующей наименьшей суммы валюты, здесь она равна 0,5.

Когда d1, cnt+1, когда d2, cnt+2, когда d3, cnt+4;

`timescale 1ns/1ns
module seller1(
	input wire clk  ,
	input wire rst  ,
	input wire d1 ,
	input wire d2 ,
	input wire d3 ,
	
	output reg out1,
	output reg [1:0]out2
);
reg[2:0]cnt;
always@(posedge clk,negedge rst)begin
	if(!rst)begin
		cnt<=0;
		out1<=0;
		out2<=0;
	end
	else begin
	if(d1)cnt<=cnt+1;
	else if(d2)cnt<=cnt+2;
	else if(d3)cnt<=cnt+4;
	else if(cnt>=3)begin
		out1<=1;
		out2<=cnt-3;
		cnt<=0;//记得复位为0,表示一个过程的结束
	end
	else begin
		out1<=0;
		out2<=0;
	end//这里需要注意一定需要这一步,不然在不复位时,将保持一直输出1的状态
	end
end
endmodule

Обратите внимание, что все d1, d2 и d3 имеют форму импульсов, то есть они будут приняты только за один временной шаг, а также обнаружение

`timescale 1ns/1ns


module seller1(
	input wire clk  ,
	input wire rst  ,
	input wire d1 ,
	input wire d2 ,
	input wire d3 ,
	
	output reg out1,
	output reg [1:0]out2
);

    parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 , S4 = 'd4, S5 = 'd5 , S6 = 'd6;
    reg  [2:0]	current_state;
    reg  [2:0]	next_state;
	wire [2:0]   input_state;//将输入组合起来
	assign input_state = {d1,d2,d3};
	
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)begin
            current_state <= S0;
        end
        else begin
            current_state <= next_state;
        end
    end   
    
    always@(*)begin
        case(current_state)
            S0:begin
				case(input_state)
					3'b100:next_state = S1 ;
					3'b010:next_state = S2 ;
					3'b001:next_state = S4 ;
					default:next_state = next_state;
				endcase	
            end
            S1:begin
            	case(input_state)
					3'b100:next_state = S2 ;
					3'b010:next_state = S3 ;
					3'b001:next_state = S5 ;
					default:next_state = next_state; 
				endcase
            end
            S2:begin
			    case(input_state)
					3'b100:next_state = S3 ;
					3'b010:next_state = S4 ;
					3'b001:next_state = S6 ;
					default:next_state = next_state;
				endcase				
            end
			
            default:begin
                next_state = S0;
            end
        endcase
    end
    
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)begin
            out1 <= 1'b0;
			out2 <= 2'b0;
        end
        else begin
			case(next_state)
					S3:		   begin out1 <= 1'b1;out2 <= 2'b0; end 
					S4:		   begin out1 <= 1'b1;out2 <= 2'b1; end 
					S5:		   begin out1 <= 1'b1;out2 <= 2'b10; end 
					S6:		   begin out1 <= 1'b1;out2 <= 2'b11; end 
					default:   begin out1 <= 1'b0;out2 <= 2'b0; end 
			endcase	
        end
    end
 
endmodule

Метод конечного автомата

Использование конечного автомата MOORE, то есть выходной сигнал связан только с состоянием и не имеет ничего общего с текущим входным сигналом.

Метод конечного автомата может поддерживать одновременную вставку нескольких монет.

МУР три секции

Первый абзац: объявление сигнала, определение состояния, переход состояния.

Второй абзац: из текущего состояния определите следующее состояние на основе входного сигнала.

Здесь видно, что если одновременно вложено несколько монет, можно выполнить перевод и решение. Просто добавьте решение в случае.

Раздел 3: Определение выходного сигнала на основе вторичного состояния

Торговый автомат (поддерживает торговлю несколькими товарами)

Когда sel равен 0, покупайте полтора доллара, что соответствует четвертому состоянию, s3; когда sel равно 1, покупайте два с половиной юаня, что соответствует шестому состоянию, s5.

Государственный аппарат

`timescale 1ns/1ns

module seller2(
	input wire clk  ,
	input wire rst  ,
	input wire d1 ,
	input wire d2 ,
	input wire sel ,
	
	output reg out1,
	output reg out2,
	output reg out3
);
//*************code***********//

    parameter S0=0, S0_5=1, S1=2, S1_5=3, S2=4, S2_5=5, S3=6;
    reg[2:0] state, nstate;
    
    always@(posedge clk or negedge rst) begin
        if(~rst)
            state <= 0;
        else
            state <= nstate;
    end
    
    always@(*) begin
        case(state)
            S0     : nstate = d1? S0_5:
                              d2? S1:
                              nstate;
            S0_5   : nstate = d1? S1:
                              d2? S1_5:
                              nstate;
            S1     : nstate = d1? S1_5:
                              d2? S2:
                              nstate;
            S1_5   : nstate = ~sel? S0:
                              d1? S2:
                              d2? S2_5:
                              nstate;
            S2     : nstate = ~sel? S0:
                              d1? S2_5:
                              d2? S3:
                              nstate;
            default: nstate = S0;
        endcase
    end
    
    always@(*) begin
        if(~rst) begin
            {out1, out2, out3} = 3'b000;
        end
        else begin
            case(state)
                S0, S0_5, S1: {out1, out2, out3} = 0;
                S1_5        : {out1, out2, out3} = ~sel? 3'b100: 3'b000;
                S2          : {out1, out2, out3} = ~sel? 3'b101: 3'b000;
                S2_5        : {out1, out2, out3} = ~sel? 3'b101: 3'b010;
                S3          : {out1, out2, out3} = ~sel? 3'b101: 3'b011;
                default     : {out1, out2, out3} = 3'b000;
            endcase
        end
    end
//*************code***********//
endmodule

Вышеупомянутый автомат представляет собой мучнистый конечный автомат, то есть выходной сигнал зависит от текущего состояния и входного сигнала. 

`timescale 1ns/1ns


module seller2(
	input wire clk  ,
	input wire rst  ,
	input wire d1 ,
	input wire d2 ,
	input wire sel ,
	
	output reg out1,
	output reg out2,
	output reg out3
);

    parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 , S4 = 'd4, S5 = 'd5, S6 = 'd6;
    reg [2:0]	current_state;
    reg [2:0]	next_state;
    wire [1:0]  input_state;
	assign input_state = {d1,d2};
	
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)begin
            current_state <= S0;
        end
        else begin
            current_state <= next_state;
        end
    end   
    
    always@(*)begin
		if (!sel) begin
			case(current_state)
			    S0:begin
					case(input_state)
						2'b10 :next_state = S1 ;
						2'b01 :next_state = S2 ;
						default:next_state = next_state;
					endcase	
			    end
			    S1:begin
			    	case(input_state)
						2'b10 :next_state = S2 ;
						2'b01 :next_state = S3 ;
						default:next_state = next_state;
					endcase	 
			    end
			    S2:begin
				    case(input_state)
						2'b10 :next_state = S3 ;
						2'b01 :next_state = S4 ;
						default:next_state = next_state;
					endcase	
			    end
			    default:  next_state = S0;  
			endcase
		end
		else begin
			case(current_state)
			    S0:begin
					case(input_state)
						2'b10 :next_state = S1 ;
						2'b01 :next_state = S2 ;
						default:next_state = next_state;
					endcase	
			    end
			    S1:begin
			    	case(input_state)
						2'b10 :next_state = S2 ;
						2'b01 :next_state = S3 ;
						default:next_state = next_state;
					endcase	 
			    end
			    S2:begin
				    case(input_state)
						2'b10 :next_state = S3 ;
						2'b01 :next_state = S4 ;
						default:next_state = next_state;
					endcase	
			    end
				S3:begin
				    case(input_state)
						2'b10 :next_state = S4 ;
						2'b01 :next_state = S5 ;
						default:next_state = next_state;
					endcase	
				end
				S4:begin
				    case(input_state)
						2'b10 :next_state = S5 ;
						2'b01 :next_state = S6 ;
						default:next_state = next_state;
					endcase	
				end
			    default:  next_state = S0;  
			endcase
			
		
		end
    end
    
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)begin
            out1 <= 1'b0;
			out2 <= 1'b0;
			out3 <= 1'b0;
        end
        else begin
			if(!sel)begin
				case (next_state)
					S3:		begin out1 <= 1'b1;out2 <= 1'b0;out3 <= 1'b0;end 
					S4:		begin out1 <= 1'b1;out2 <= 1'b0;out3 <= 1'b1;end 
					default:begin out1 <= 1'b0;out2 <= 1'b0;out3 <= 1'b0;end 
				endcase
			end
			else begin
				case (next_state)	
					S5:		begin out1 <= 1'b0;out2 <= 1'b1;out3 <= 1'b0;end 	
					S6:		begin out1 <= 1'b0;out2 <= 1'b1;out3 <= 1'b1;end 	
					default:begin out1 <= 1'b0;out2 <= 1'b0;out3 <= 1'b0;end 	
				endcase	
			end
        end
    end
 
endmodule

Вышеуказанное представляет собой стандартный код конечного автомата MOORE, то есть выходные данные относятся только к вторичному состоянию.

Во время перехода состояний обязательно не забудьте написать

Это эквивалентно  последующему сбросу, иначе нет возможности выполнить сброс.

рекомендация

отblog.csdn.net/m0_73553411/article/details/135130144