题解 | 自动贩售机1

一、因为投币信号只保持半个周期,所以需要一个reg储存,以保证持续一个完整周期;

当然,如果不搞这个reg,那么在投币时,next状态保持也行;

然后会出现一个问题,如果连续投币呢?

二、testbench里面用的是@时钟沿写法,这样上升沿是能捕捉到当前变化的投币信号的,不会出现投币信号上升沿出现半个周期,reg在下个上升沿不到的情况;否则还得写negedge捕捉了;

`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
);
//*************code***********//
parameter S0=0,S05=1,S10=2,S15=3,S20=4,S25=5,S30=6;
reg [2:0]state,next;
reg d1r,d2r,d3r;
always@(posedge clk or negedge rst)
    if (~rst)
		state <= S0;
	else
		state <= next;

always@(posedge clk or negedge rst)
    if (~rst) begin
		d1r <= 0;
        d2r <= 0;
        d3r <= 0;
    end
	else begin
		d1r <= d1;
        d2r <= d2;
        d3r <= d3;   
    end


always@(*)
    if (~rst)
		next = S0;
	else case(state)
		S0 : next = {d1r,d2r,d3r}==3'b100 ? S05:      //0     //0.5 1.0 2.0
				    {d1r,d2r,d3r}==3'b010 ? S10:
				    {d1r,d2r,d3r}==3'b001 ? S20: state;
		S05: next = {d1r,d2r,d3r}==3'b100 ? S10:      //0.5
				    {d1r,d2r,d3r}==3'b010 ? S15:
				    {d1r,d2r,d3r}==3'b001 ? S25: state;
		S10: next = {d1r,d2r,d3r}==3'b100 ? S15:      //1.0
				    {d1r,d2r,d3r}==3'b010 ? S20:
				    {d1r,d2r,d3r}==3'b001 ? S30: state;

		S15: next = {d1r,d2r,d3r}==3'b100 ? S05:      //1.5
				    {d1r,d2r,d3r}==3'b010 ? S10:
				    {d1r,d2r,d3r}==3'b001 ? S20: 
                    {d1r,d2r,d3r}==3'b000 ? S0 :next;
		S20: next = {d1r,d2r,d3r}==3'b100 ? S05:      //2.0
				    {d1r,d2r,d3r}==3'b010 ? S10:
				    {d1r,d2r,d3r}==3'b001 ? S20:
                    {d1r,d2r,d3r}==3'b000 ? S0 :next;
		S25: next = {d1r,d2r,d3r}==3'b100 ? S05:      //2.5
				    {d1r,d2r,d3r}==3'b010 ? S10:
				    {d1r,d2r,d3r}==3'b001 ? S20:
                    {d1r,d2r,d3r}==3'b000 ? S0 :next;
		S30: next = {d1r,d2r,d3r}==3'b100 ? S05:      //3.0
				    {d1r,d2r,d3r}==3'b010 ? S10:
				    {d1r,d2r,d3r}==3'b001 ? S20:
                    {d1r,d2r,d3r}==3'b000 ? S0 :next;
		default: next = S0;
	endcase

always@(posedge clk or negedge rst)
    if (~rst) begin
		out1 <= 1'b0;
		out2 <= 2'd0;
	end
	else begin
		case (next)
		S15:begin out1 <= 1'b1; out2 <= 2'd0; end
		S20:begin out1 <= 1'b1; out2 <= 2'd1; end
		S25:begin out1 <= 1'b1; out2 <= 2'd2; end
		S30:begin out1 <= 1'b1; out2 <= 2'd3; end
		default: begin out1 <= 1'b0; out2 <= 2'd0; end
		endcase
	end

//*************code***********//
endmodule

全部评论
图中说的保持是指在S00 S10 S15的状态下未投币为next;当然本代码这里也可以是next,因为参考变化点在整个时钟周期不会变化了;
点赞 回复 分享
发布于 01-20 17:00 湖北

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务