//UART接收器
module UART_RCVR #(parameter word_size=8,half_word=word_size/2)(
output [word_size-1:0] RCV_datareg,
output read_not_ready_out,Error1,Error2,
input Serial_in,read_not_ready_in,
Sample_clk,rst_b
);
Control_Unit M0(read_not_ready_out,Error1,Error2,clr_Sample_counter,
inc_Sample_counter,clr_Bit_counter,inc_Bit_counter,
shift,load,read_not_ready_in,Ser_in_0,SC_eq_3,SC_It_7,
BC_eq_8,Sample_clk,rst_b);
Datapath_Unit M1(RCV_datareg,Ser_in_0,SC_eq_3,SC_It_7,BC_eq_8,Serial_in,
clr_Sample_counter,inc_Sample_counter,clr_Bit_counter,
inc_Bit_counter,shift,load,Sample_clk,rst_b);
endmodule
module Control_Unit #(
parameter word_size = 8,
half_word=word_size/2,
Num_state_bits=2,
idle = 2'b00,
starting = 2'b01,
receiving = 2'b10)
(output reg read_not_ready_out,Error1,Error2,
clr_Sample_counter,inc_Sample_counter,
clr_Bit_counter,inc_Bit_counter,shift,load,
input read_not_ready_in,Ser_in_0,SC_eq_3,SC_It_7,
BC_eq_8,Sample_clk,rst_b
);
reg [word_size-1:0] RCV_shftreg;
reg [Num_state_bits-1:0] state,next_state;
always@(posedge Sample_clk)
if(!rst_b)
state <= idle;
else
state <= next_state;
always@(state,Ser_in_0,SC_It_7,SC_eq_3,read_not_ready_in)begin
read_not_ready_out = 0;
clr_Bit_counter = 0;
clr_Sample_counter = 0;
inc_Sample_counter = 0;
inc_Bit_counter = 0;
shift = 0;
load = 0;
Error1 = 0;
Error2 = 0;
next_state = idle;
case(state)
idle: if(Ser_in_0==1'b1)
next_state = starting;
else
next_state = idle;
starting:if(Ser_in_0==1'b0)begin
clr_Sample_counter = 1;
next_state = receiving;
end
else if(SC_eq_3==1'b1)begin
next_state = receiving;
clr_Sample_counter = 1;
end
else begin
next_state = starting;
inc_Sample_counter = 1;
end
receiving:if(SC_It_7==1)begin
inc_Sample_counter = 1;
next_state = receiving;
end
else begin
clr_Sample_counter = 1;
if(!BC_eq_8)begin
shift = 1;
inc_Bit_counter = 1;
next_state = receiving;
end
else begin
next_state = idle;
read_not_ready_out = 1;
clr_Bit_counter = 1;
if(read_not_ready_in==1'b1)
Error1 = 1;
else if(Ser_in_0==1'b1)
Error2 = 1;
else
load = 1;
end
end
default: next_state = idle;
endcase
end
endmodule
module Datapath_Unit #(
parameter word_size = 8,
half_word = word_size/2,
Num_counter_bits = 4
)(
output reg [word_size-1:0] RCV_datareg;
output Ser_in_0,SC_It_7,SC_eq_3,BC_eq_8,
input Serial_in,clr_Sample_counter,inc_Sample_counter,
clr_Bit_counter,inc_Bit_counter,shift,load,
input shift,load,Sample_clk,rst_b
);
reg [word_size-1:0] RCV_shftreg;
reg [Num_counter_bits-1:0] Sample_counter;
reg [Num_counter_bits:0] Bit_counter;
assign Ser_in_0 = (Serial_in==1'b0);
assign BC_eq_8 = (Bit_counter==word_size);
assign SC_It_7 = (Sample_counter<word_size-1);
assign SC_eq_3 = (Sample_counter == half_word-1);
always@(posedge Sample_clk)
if(!rst_b)begin
Sample_counter <= 0;
Bit_counter <= 0;
RCV_datareg <= 0;
RCV_shftreg <= 0;
end
else begin
if(clr_Sample_counter==1)
Sample_counter <= 0;
else if(inc_Sample_counter==1)
Sample_counter <= Sample_counter+1;
if(clr_Bit_counter==1)
Bit_counter <= 0;
else if(inc_Bit_counter==1)
Bit_counter <= Bit_counter+1;
if(shift ==1)
RCV_shftreg <= {Serial_in,RCV_shftreg[word_size-1:1]};
if(load==1)
RCV_datareg <= RCV_shftreg;
end
endmodule