오늘은 UART를 제작하는 전반적인 과정을 담아보겠습니다.

전체적인 Block입니다. DATA가 버스를 통해 병렬로 UART TX로 전달되면 TX에서는 FIFO를 통해서 RX로 전달하고 RX에서는 다시 병렬로 DATA 버스로 저장하는 과정을 담아보겠습니다.

 


input_data_bus

더보기
`timescale 1ns / 1ps
module data_bus(
    input CLK,
    input RST,
    input [7:0] DIN,
    output reg DOUT0,
    output reg DOUT1,
    output reg DOUT2,
    output reg DOUT3,
    output reg DOUT4,
    output reg DOUT5,
    output reg DOUT6,
    output reg DOUT7
);

reg [2:0] data_cnt;
reg [7:0] bus [7:0];
reg full;

integer i;
initial begin
    full <= 0;
    data_cnt <= 0;
    for(i = 0; i <8; i = i + 1)
    bus[i] <= 8'd0;
end

always @(posedge CLK or posedge RST) begin
    if (RST) begin
        data_cnt <= 0;
        full <= 0;
        {DOUT7, DOUT6, DOUT5, DOUT4, DOUT3, DOUT2, DOUT1, DOUT0} <= 8'd0;
    end
    else begin
        if (DIN != 0) begin
            bus[data_cnt] <= DIN;
            if(data_cnt == 7) begin
                data_cnt <= 0;
                full <= 1;
            end
            else begin
                data_cnt <= data_cnt + 1;
            end     
        end
        if (full) begin
            {DOUT7, DOUT6, DOUT5, DOUT4, DOUT3, DOUT2, DOUT1, DOUT0} <= bus[data_cnt];
            data_cnt <= data_cnt + 1;
            end
    end
end

endmodule

 

 


data_bus_tb

더보기
`timescale 1ns / 1ps

module data_bus_tb();

// Declare input signals
reg CLK;
reg RST;
reg [7:0] DIN;

// Declare 125MHz CLK
parameter CLK_PD = 8.0;

// Declare output signals
wire DOUT0, DOUT1, DOUT2, DOUT3, DOUT4, DOUT5, DOUT6, DOUT7;

// Instantiate the data_bus module
data_bus uut (
    .CLK(CLK),
    .RST(RST),
    .DIN(DIN),
    .DOUT0(DOUT0),
    .DOUT1(DOUT1),
    .DOUT2(DOUT2),
    .DOUT3(DOUT3),
    .DOUT4(DOUT4),
    .DOUT5(DOUT5),
    .DOUT6(DOUT6),
    .DOUT7(DOUT7)
);

// Clock generation
always begin
    #(CLK_PD/2) CLK = ~CLK;  // Generate clock with 10ns period
end

// Test scenario
initial begin
    // Initialize inputs
    CLK = 0;
    RST = 1;
    DIN = 8'h00;
    
    // Release reset
    #(3*CLK_PD) RST = 0;
    
    // Test data input
    #CLK_PD DIN = 8'h01;
    #CLK_PD DIN = 8'h23;
    #CLK_PD DIN = 8'h45;
    #CLK_PD DIN = 8'h67;
    #CLK_PD DIN = 8'h89;
    #CLK_PD DIN = 8'hAB;
    #CLK_PD DIN = 8'hCD;
    #CLK_PD DIN = 8'hEF;
    
    // Set DIN to 0 to trigger output phase
    #10 DIN = 8'h00;
    
    // Wait for sufficient time to observe all outputs
    #100 $finish;
end

endmodule

 

 


Simulation

순차적 데이터 병력 출력 확인.

 

No Mark