题目要求在上一题[Q131 Serial receiver]的基础上增加数据输出的逻辑,状态机和done信号输出的逻辑还是和上一题相同,无需改变,只需要在数据同步期间将数据接收下来即可,同时注意发送数据是先送低位还是先送高位。
从图中可以看出是先送低位,只需要增加一个移位寄存器,在DATA状态对数据进行移位即可。
比较简单直接贴上代码
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
// Use FSM from Fsm_serial
parameter IDLE = 3'd0;
parameter START = 3'd1;
parameter DATA = 3'd2;
parameter STOP = 3'd3;
parameter ERROR = 3'd4;
reg [2:0] curr_state;
reg [2:0] next_state;
reg [2:0] dat_cnt;
reg done_r1;
wire done_r;
always @(posedge clk) begin
if(reset==1'b1) begin
curr_state <= IDLE;
end
else begin
curr_state <= next_state;
end
end
always @(*) begin
case(curr_state)
IDLE:begin
if(in == 1'b0) begin
next_state = DATA;
end
else begin
next_state = IDLE;
end
end
DATA:begin
if(dat_cnt == 3'd7) begin
next_state = STOP;
end
else begin
next_state = DATA;
end
end
STOP:begin
if( in == 1'b1) begin
next_state = IDLE;
end
else begin
next_state = ERROR;
end
end
ERROR: begin
if( in == 1'b1) begin
next_state = IDLE;
end
else begin
next_state = ERROR;
end
end
default: next_state= IDLE;
endcase
end
always @(posedge clk) begin
if(reset == 1'b1) begin
dat_cnt <= 3'd0;
end
else if(curr_state == DATA) begin
dat_cnt <= dat_cnt + 1'b1;
end
else begin
dat_cnt <= 3'd0;
end
end
always @(posedge clk) begin
if(reset == 1'b1) begin
done_r <= 1'b0;
end
else begin
done_r <= (curr_state == STOP) && (in == 1'b1);
end
end
assign done = done_r;
// New: Datapath to latch input bits.
reg [7:0] out_reg;
always @(posedge clk) begin
if(reset) begin
out_reg <= 8'd0;
end
else begin
if(curr_state == DATA) begin
out_reg <={in,out_reg[7:1]};//先送低位
end
else begin
out_reg <= out_reg;
end
end
end
assign out_byte = out_reg;
endmodule