공부방/Verilog_노진호교수님_서울기술교육센터_필기

240516 FSM_COUNTER , ILA , UART

맘스터치보단파파이스 2024. 5. 16. 16:51

NOT 위치에 따라서 detect를 posedge OR negedge 어디서 detect 할 것인지 파악.

NOT이 위에 있을 땐 negedge

NOT이 아래에 있을 땐 posedge

 

<< IP CAtalog >>

system debug

 

ila_0 your_instance_name (
	.clk(clk), // input wire clk


	.probe0(probe0), // input wire [0:0]  probe0  
	.probe1(probe1), // input wire [0:0]  probe1 
	.probe2(probe2), // input wire [0:0]  probe2 
	.probe3(probe3), // input wire [0:0]  probe3 
	.probe4(probe4), // input wire [13:0]  probe4 
	.probe5(probe5) // input wire [3:0]  probe5
);

`timescale 1ns / 1ps

module uart (
    input clk,
    input reset,
    input start,
    input [7:0] tx_data,
    output tx_done,
    output txd
);

    wire br_tick;

    buadrate_generator U_BR_Gen (
        .clk(clk),
        .reset(reset),
        .br_tick(br_tick)
    );

    transmitter U_TxD (
        .clk(clk),
        .reset(reset),
        .br_tick(br_tick),
        .start(start),
        .data(tx_data),
        .tx_done(tx_done),
        .tx(txd)
    );
endmodule

module buadrate_generator (
    input  clk,
    input  reset,
    output br_tick
);
    reg [$clog2(100_000_000 / 9600)-1 : 0] counter_reg, counter_next;
    reg tick_reg, tick_next;

    assign br_tick = tick_reg;

    always @(posedge clk, posedge reset) begin
        if (reset) begin
            counter_reg <= 0;
            tick_reg <= 1'b0;
        end else begin
            counter_reg <= counter_next;
            tick_reg <= tick_next;
        end
    end

    always @(*) begin
        //if (counter_reg == 100_000_000 / 9600 - 1) begin
        if (counter_reg == 10- 1) begin
            counter_next = 0;
            tick_next = 1'b1;
        end else begin
            counter_next = counter_reg + 1;
            tick_next = 1'b0;
        end
    end
endmodule

module transmitter (
    input clk,
    input reset,
    input br_tick,
    input start,
    input [7:0] data,
    output tx_done,
    output tx
);
    localparam IDLE = 0, START = 1, STOP = 10;
    localparam D0 = 2, D1 = 3, D2 = 4, D3 = 5, D4 = 6, D5 = 7, D6 = 8, D7 = 9;

    reg [3:0] state, state_next;
    reg [7:0] r_data;
    reg tx_reg, tx_next;
    reg tx_done_reg, tx_done_next;

    assign tx = tx_reg;
    assign tx_done = tx_done_reg;

    // STATE REGISTER
    always @(posedge clk, posedge reset) begin
        if (reset) begin
            state = IDLE;
            tx_reg <= 1'b0;
            tx_done_reg <= 1'b0;
        end else begin
            state  <= state_next;
            tx_reg <= tx_next;
            tx_done_reg <= tx_done_next;
        end
    end

    //NEXT STATE COMBINATIONAL LOGIC
    always @(*) begin
        state_next = state;
        case (state)
            IDLE: if (start) state_next = START;
            START: if (br_tick) state_next = D0;
            D0: if (br_tick) state_next = D1;
            D1: if (br_tick) state_next = D2;
            D2: if (br_tick) state_next = D3;
            D3: if (br_tick) state_next = D4;
            D4: if (br_tick) state_next = D5;
            D5: if (br_tick) state_next = D6;
            D6: if (br_tick) state_next = D7;
            D7: if (br_tick) state_next = STOP;
            STOP: if (br_tick) state_next = IDLE;
        endcase
    end
    //OUTPUT COMBINATIONAL LOGIC
    always @(*) begin
        tx_next = tx_reg;
        tx_done_next = 1'b0;
        case (state)
            IDLE: tx_next = 1'b1;
            START: begin
                tx_next <= 1'b0;
                r_data = data;
            end
            D0:   tx_next = r_data[0];
            D1:   tx_next = r_data[1];
            D2:   tx_next = r_data[2];
            D3:   tx_next = r_data[3];
            D4:   tx_next = r_data[4];
            D5:   tx_next = r_data[5];
            D6:   tx_next = r_data[6];
            D7:   tx_next = r_data[7];
            STOP: begin 
                tx_next = 1'b1;
                if(state_next == IDLE) tx_done_next = 1'b1;
            end
        endcase
    end
endmodule
`timescale 1ns / 1ps

module tb_uart();
    reg clk;
    reg  reset;
    reg  start;
    reg [7:0]tx_data;
    wire tx_done;
    wire txd;

    

    uart dut(
        .clk(clk),
        .reset(reset),
        .start(start),
        .tx_data(tx_data),
        .tx_done(tx_done),
        .txd(txd)
    );

    always #5 clk =~clk;

    initial begin
        clk = 1'b0;
        reset = 1'b1;
        start = 1'b0;
        tx_data = 0;
    end

    initial begin
        #20 reset = 1'b0;
        #20 tx_data = 8'haa; start = 1'b1;
        #10 start = 1'b0;
    end

endmodule