Skip to content

Instantly share code, notes, and snippets.

@sharuijinfriend
Last active September 5, 2020 08:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sharuijinfriend/72527ef9a55a824faeb086c69da085a1 to your computer and use it in GitHub Desktop.
Save sharuijinfriend/72527ef9a55a824faeb086c69da085a1 to your computer and use it in GitHub Desktop.
2020/09/05兆易创新笔试题(buffer串行接口通信/个人瞎写不确定是否有逻辑语法错误)
module Buffer
(
input clk,
input rstn,
input DATA_IN,
input REQ_READ,
input ACK,
output REQ_WRITE,
output [15:0] DATA_OUT
);
parameter D1=3'd0;
parameter D2=3'd1;
parameter D3=3'd2;
parameter D4=3'd3;
parameter D5=3'd4;
parameter IDLE=3'd5;
reg REQ_WRITE;
reg [15:0] DATA_OUT;
reg [2:0] d_curr_state, d_next_state;
always @(posedge clk, negedge rstn)
if(~rstn)
d_curr_state<=D1;
else
d_curr_state<=d_next_state;
always @(*)
begin
if(d_curr_state==IDLE)
begin
if(REQ_READ)
d_next_state=D1;
else
d_next_state=IDLE;
end
else
begin
case(d_curr_state)
D1: if(REQ_WRITE && ACK && DATA_IN)
d_next_state=D2;
else
d_next_state=D1;
D2:if(REQ_WRITE && ACK && ~DATA_IN)
d_next_state=D3;
else
d_next_state=D2;
D3:if(REQ_WRITE && ACK && DATA_IN)
d_next_state=D4;
else
d_next_state=D1;
D4:if(REQ_WRITE && ACK && DATA_IN)
d_next_state=D3;
else
d_next_state=D2;
D5:if(REQ_WRITE && ACK && ~DATA_IN)
d_next_state=IDLE;
else
d_next_state=D2;
default: d_next_state=D1;
endcase
end
end
reg frame_head_valid;
always @(posedge clk, negedge rstn)
if(~rstn)
frame_head_valid<=0;
else if(curr_state==IDLE && REQ_READ)
frame_head_valid<=0;
else if(d_curr_state==D5 && REQ_WRITE && ACK && ~DATA_IN)
frame_head_valid<=1;
reg [15:0] buffer_reg;
reg [1:0] data_curr_state;
reg [1:0] data_next_state;
parameter DATA_IDLE=2'd0;
parameter DATA_S1=2'd1;
parameter DATA_S2=2'd2;
parameter DATA_READ=2'd3;
reg [3:0] data_cnt;
reg [8:0] data_tem;
wire data_correct;
always @(posedge clk, negedge rstn)
if(~rstn)
data_curr_state<=DATA_IDLE;
else
data_curr_state<=data_next_state;
always @(*)
case(data_curr_state)
DATA_IDLE:if(frame_head_valid)
data_next_state=DATA_S1;
else
data_next_state=DATA_IDLE;
DATA_S1:if(data_correct && ACK && data_cnt==4'd8)
data_next_state=DATA_S2;
else
data_next_state=DATA_S1;
DATA_S2: if(data_correct && ACK && data_cnt=4'd8)
data_next_state=DATA_READ;
else
data_next_state=DATA_S2;
DATA_READ:if(REQ_READ)
data_next_state=DATA_IDLE;
else
data_next_state=DATA_READ;
endcase
always @(posedge clk, negedge rstn)
if(~rstn)
begin
data_cnt<=0;
data_tem<=0;
end
else
begin
if(data_curr_state==DATA_S1 || data_curr_state==DATA_S2)
begin
if(ACK)
begin
data_tem<={data_tem[0+:8],DATA_IN};
if(data_cnt==4'd8)
data_cnt<=0;
else
data_cnt<=data_cnt+1;
end
end
assign data_correct=((^data_tem[1+:8])==(~data_tem[0]))?1:0;
always @(posedge clk, negedge rstn)
if(~rstn)
buffer_reg<=0;
else
case(curr_state)
DATA_S1:if(data_correct && ACK && data_cnt==4'd8)
buffer_reg[0+:8]<=data_tem[1+:8];
DATA_S2:if(data_correct && ACK && data_cnt==4'd8)
buffer_reg[8+:8]<=data_tem[1+:8];
endcase
always @(posedge clk, negedge rstn)
if(~rstn)
begin
REQ_WRITE<=1;
DATA_OUT<=0;
end
else
case(curr_state)
DATA_S2:if(data_correct && ACK && data_cnt==4'd8)
REQ_WRITE<=0;
DATA_READ: if(REQ_READ)
begin
REQ_WRITE<=1;
DATA_OUT<=buffer_reg;
end
endcase
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment