торговый автомат
если наивный метод
Одна из идей состоит в том, чтобы использовать регистр 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, то есть выходные данные относятся только к вторичному состоянию.
Во время перехода состояний обязательно не забудьте написать
Это эквивалентно последующему сбросу, иначе нет возможности выполнить сброс.