//兄弟们,我发现这个牛客平台的自仿真平台是真的有毒,下面这个代码我modelsim仿真没问题,这就不对了,吐了吐了
`timescale 1ns/1ns
module data_driver(
    input clk_a,
    input rst_n,
    input data_ack,
    output reg [3:0]data,
    output reg data_req
    );
    
    
    reg data_ack_d0_r;
    reg data_ack_d1_r;
    reg data_ack_d2_r;
    
    always @(posedge clk_a or negedge rst_n) begin
        if (!rst_n) begin
            data_ack_d0_r <= 'd0;
            data_ack_d1_r <= 'd0;
            data_ack_d2_r <= 'd0;
        end
        else begin
            data_ack_d0_r <= data_ack;
            data_ack_d1_r <= data_ack_d0_r;
            data_ack_d2_r <= data_ack_d1_r;
        end
    end

    always @(posedge clk_a or negedge rst_n) begin
        if (!rst_n) begin
            data <= 'd0;
        end
        else if (data_ack_d1_r & !data_ack_d2_r) begin
            data <= data == 'd7 ? 'd0 : data + 'd1;
        end
    end
    
    reg [3-1:0] cnt_r;
    always @(posedge clk_a or negedge rst_n) begin
        if (!rst_n) begin
            cnt_r <= 'd0;
        end
        else if (data_ack_d1_r & !data_ack_d2_r) begin
            cnt_r <= 'd0;
        end
        else if (data_req) begin
            cnt_r <= cnt_r;
        end
        else begin
            cnt_r <= cnt_r + 'd1;
        end
    end
    
    
    always @(posedge clk_a or negedge rst_n) begin
        if (!rst_n) begin
            data_req <= 'd0;
        end
        else if (data_ack_d1_r) begin
            data_req <= 'd0;
        end
        else if (cnt_r == 'd4) begin
            data_req <= 'd1;
        end
    end
endmodule


module data_receiver(
    input clk_b,
    input rst_n,
    input [3:0]data,
    input data_req,
    output reg data_ack
    );
    
    reg data_req_d0_r;
    reg data_req_d1_r;
    reg data_r;
    always @(posedge clk_b or negedge rst_n) begin
        if (!rst_n) begin
            data_req_d0_r <= 'd0;
            data_req_d1_r <= 'd0;
        end
        else begin
            data_req_d0_r <= data_req;
            data_req_d1_r <= data_req_d0_r;
        end
    end
    
    always @(posedge clk_b or negedge rst_n) begin
        if (!rst_n) begin
            data_r <= 'd0;
            data_ack <= 'd0;
        end
        else if (data_req_d1_r) begin
            data_r <= data;
            data_ack <= 'd1;
        end
        else begin
            data_ack <= 'd0;
        end
    end
    
    
    
endmodule

/*`timescale 1ns/1ns
module data_driver(
    input clk_a,
    input rst_n,
    input data_ack,
    output reg [3:0]data,
    output reg data_req
    );
    
    reg [2:0] data_cnt;
    reg [1:0]ack_r;
    parameter idle = 4'b0001;
    parameter state_req=4'b0010;
    parameter state_ack=4'b0100;
    parameter state_data_change=4'b1000;
    
    reg [3:0] c_state;
    reg [3:0] n_state;
    
    always @(posedge clk_a or negedge rst_n) begin
        if(!rst_n)
            ack_r <= 2'd0;
        else
            ack_r <= {ack_r[0],data_ack};
    end
    
    always @(posedge clk_a or negedge rst_n) begin
        if(!rst_n)
            c_state <= idle;
        else
            c_state <= n_state;
    end
    
    always@(*) begin
        case(c_state)
            idle: begin
                if(data_req) n_state <= state_req;
                else n_state <= c_state;
            end
            state_req: begin
                if(ack_r[1]) n_state <= state_ack;
                else n_state <= c_state;
            end
            state_ack: begin
                n_state <=  state_data_change;                  
            end
            state_data_change: begin
                if(data_cnt == 3'd4) n_state <= idle;
                else n_state <= c_state;
            end
            default: n_state <= idle;
        endcase
    end
    
    always @(posedge clk_a or negedge rst_n)begin
        if(!rst_n) begin
           data_req <= 1'b0;
        end
        else begin
            case(c_state)
                idle: begin
                    data_req <= 1'b1;
                end
                state_ack: begin
                    data_req <= 1'b0;
                end
            endcase
        end
    end
    
    always @(posedge clk_a or negedge rst_n) begin
        if(!rst_n)
            data_cnt <= 3'd0;
        else if(c_state == state_ack) begin
            if(data_cnt == 3'd4)
                data_cnt <= 3'd0;
            else
                data_cnt <= data_cnt + 1'b1;
        end
        else
            data_cnt <= 3'd0;
    end
    
    always @(posedge clk_a or negedge rst_n) begin
        if(!rst_n)
            data <= 4'd0;
        else if(c_state == state_ack) begin
            if(data==4'd7)
                data <= 4'd0;
            else
                data <= data + 1'b1;
        end
        else
            data <= data;
    end
    
endmodule
     
module data_receiver(
    input clk_b,
    input rst_n,
    input [3:0] data,
    input data_req,
    output reg data_ack
);
    reg [3:0] data_r;
    reg [1:0] req_r;
    
    always @(posedge clk_b or negedge rst_n) begin
        if(!rst_n)
            req_r <= 2'd0;
        else
            req_r <= {req_r[0],data_req};
    end
    
    always @(posedge clk_b or negedge rst_n) begin
        if(!rst_n) begin
            data_ack <= 1'b0;
            data_r <= 4'd0;
        end
        else if(req_r[1]) begin
           data_ack <= 1'b1;
            data_r <= data;
        end
        else begin
            data_ack <= 1'b0;
            data_r <= data_r;
        end
    end
endmodule*/