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 --- ![image](https://hackmd.io/_uploads/SkmbLhG8a.png)