UART 作業
---
B1105167 張家凱
FPGA呈現
---
[影片連結](https://youtu.be/bnsP-E6n6Qc)
Verilog code
---
```verilog=
//top module
`timescale 1ns / 1ps
module rx_top(
input clk,
input rst,
input rx_pin_in,
output [7:0] seg7
) ;
wire rx_pin_H2L;
H2L_detect rx_in_detect(
.clk( clk ),
.rst( rst ),
.pin_in( rx_pin_in ),
.sig_H2L( rx_pin_H2L )
);
wire rx_band_sig;
wire clk_bps;
rx_band_gen rx_band_gen(
.clk( clk ),
.rst( rst ),
.band_sig( rx_band_sig ),
.clk_bps( clk_bps )
);
wire [7:0] rx_data;
rx_ctl rx_ctl(
.clk( clk ),
.rst( rst ),
.rx_pin_in( rx_pin_in ),
.rx_pin_H2L( rx_pin_H2L ),
.rx_band_sig( rx_band_sig ),
.rx_clk_bps( clk_bps ),
.rx_data( rx_data ),
.rx_done_sig( rx_done_sig )
);
ASCII2seg7 u_ASCII2seg7(
.rst( rx_done_sig ),
.ASCII( rx_data ),
.seg7_out(seg7)
);
endmodule
```
```verilog=
`timescale 1ns / 1ps
module rx_band_gen(
input clk,
input rst,
input band_sig,
output reg clk_bps
);
parameter SYS_RATE = 125000000;
parameter BAND_RATE = 9600;
parameter CNT_BAND = SYS_RATE / BAND_RATE;
parameter HALF_CNT_BAND = CNT_BAND / 2;
reg [13:0]cnt_bps;
always @( posedge clk or posedge rst )
if( rst )
begin
cnt_bps <= HALF_CNT_BAND;
clk_bps <= 1'b0;
end
else if( !band_sig )
begin
cnt_bps <= HALF_CNT_BAND;
clk_bps <= 1'b0;
end
else if( cnt_bps == CNT_BAND )
begin
cnt_bps <= 14'd0;
clk_bps <= 1'b1;
end
else
begin
cnt_bps <= cnt_bps + 1'b1;
clk_bps <= 1'b0;
end
endmodule
```
```verilog=
`timescale 1ns / 1ps
module H2L_detect(
input clk,
input rst,
input pin_in,
output sig_H2L
);
reg pin_pre;
assign sig_H2L = !pin_in & pin_pre;
always @( posedge clk or posedge rst )
if( rst )
pin_pre <= 1'b0;
else
pin_pre <= pin_in;
endmodule
```
```verilog=
module ASCII2seg7 (
rst,
ASCII,
seg7_out
);
input rst;
input [7:0] ASCII;
reg [7:0] seg7;
output [7:0] seg7_out;
always@( posedge rst )
begin
//if ( rst ) begin
case (ASCII)
8'b0011_0000:
seg7=8'b00000011;
8'b0011_0001:
seg7=8'b10011111;
8'b0011_0010:
seg7=8'b00100101;
8'b0011_0011:
seg7=8'b00001101;
8'b0011_0100:
seg7=8'b10011001;
8'b0011_0101:
seg7=8'b01001001;
8'b0011_0110:
seg7=8'b01000001;
8'b0011_0111:
seg7=8'b00011111;
8'b0011_1000:
seg7=8'b00000001;
8'b0011_1001:
seg7=8'b00001001;
8'b0100_0001:
seg7=8'b00010001;
8'b0100_0010:
seg7=8'b11000001;
8'b0100_0011:
seg7=8'b11100101;
8'b0100_0100:
seg7=8'b10000101;
8'b0100_0101:
seg7=8'b01100001;
8'b0100_0110:
seg7=8'b01110001;
default:
seg7=8'b01100001;
endcase
end
assign seg7_out=seg7;
endmodule
```
```verulog=
`timescale 1ns / 1ps
module rx_ctl(
input clk,
input rst,
input rx_pin_in,
input rx_pin_H2L,
output reg rx_band_sig,
input rx_clk_bps,
output reg[7:0] rx_data,
output reg rx_done_sig
) ;
localparam [3:0] IDLE = 4'd0, BEGIN = 4'd1, DATA0 = 4'd2,
DATA1 = 4'd3, DATA2 = 4'd4, DATA3 = 4'd5,
DATA4 = 4'd6, DATA5 = 4'd7, DATA6 = 4'd8,
DATA7 = 4'd9, END = 4'd10, BFREE = 4'd11;
reg [3:0] pos;
always@( posedge clk or posedge rst )
if( rst )
begin
rx_band_sig <= 1'b0;
rx_data <= 8'd0;
pos <= IDLE;
rx_done_sig <= 1'b0;
end
else
case( pos )
IDLE:
if( rx_pin_H2L)
begin
rx_band_sig <= 1'b1;
pos <= pos + 1'b1;
rx_data <= 8'd0;
end
BEGIN:
if( rx_clk_bps)
begin
if( rx_pin_in == 1'b0 )
begin
pos <= pos + 1'b1;
end
else
begin
rx_band_sig <= 1'b0;
pos <= IDLE;
end
end
DATA0,DATA1,DATA2,DATA3,DATA4,DATA5,DATA6,DATA7:
if( rx_clk_bps)
begin
rx_data[ pos - DATA0 ] <= rx_pin_in;
pos <= pos + 1'b1;
end
END:
if( rx_clk_bps)
begin
rx_done_sig <= 1'b1;
pos <= pos + 1'b1;
rx_band_sig <= 1'b0;
end
BFREE:
begin
rx_done_sig <= 1'b0;
pos <= IDLE;
end
endcase
endmodule
```
testbench
---
```verilog=
`timescale 1ns / 1ps
module rx_top_tb();
reg clk;
reg rst;
reg uart_rx;
wire [7:0] seg7;
integer i;
reg [7:0] data_test=8'b0;
// 100MHz 9600bps
rx_top u_rx_top(
.clk(clk),
.rst(rst),
.rx_pin_in(uart_rx),
.seg7(seg7)
);
initial begin
clk=0;
for (i=0;i<256;i=i+1) begin //8 bit 測256個資料
rst=1;
#15 rst=0;uart_rx=1;
#260415 uart_rx=0;
#260415 uart_rx = data_test[0];
#260415 uart_rx = data_test[1];
#260415 uart_rx = data_test[2];
#260415 uart_rx = data_test[3];
#260415 uart_rx = data_test[4];
#260415 uart_rx = data_test[5];
#260415 uart_rx = data_test[6];
#260415 uart_rx = data_test[7];
#260415 uart_rx=1;
data_test = data_test + 1;
end
$finish;
end
always #10 clk=~clk;
endmodule
```
Schematic
---
