モノ創りで国造りを

ハード/ソフト問わず知見をまとめてます

VerilogでUART送信

前置き

先日UARTの受信を作成した。今回は送信。

方針

START信号を検出する。 外部データをBuffに入力。
スタートビットを出力。 クロックをカウントし、ボーレートのタイミングで信号を1bitずつ送信する。
信号送信回数をカウントする。 9回目のカウントで、出力を終えて初期化。

ソースコード

Verilog-HDL

module uart_tx(
    input[7:0]      UARTDATA,
    input             CLK,
    input             RST,
    input             START,
    output reg      UARTTX 
);
    reg[7:0] uartTxBuff = 8'b0;
    reg[8:0] clkCnt     = 9'b0;
    reg[3:0] dataCnt    = 4'b0;
    reg       sendEn    = 0;
    
parameter UARTTIMING = 9'd434;//CLK/Baudrate  ex)5oMHz/115200
    
always@(posedge CLK or negedge RST)begin
    if(!RST)begin
        clkCnt  <= 9'b0;
        dataCnt     <= 4'b0;
    end
    else if(sendEn)begin
        if(clkCnt != UARTTIMING)begin
            clkCnt <= clkCnt + 9'b1;
        end
        else begin//clkCnt == UARTTIMING
            clkCnt              <= 9'b0;
            dataCnt             <= dataCnt + 4'b1;
            UARTTX              <= uartTxBuff[7];
            uartTxBuff[7:0]     <= {uartTxBuff[6:0], 1'b1};//"1" means stop bit

            if(dataCnt == 4'b1001)begin
                sendEn  <= 0;
                clkCnt  <= 9'b0;
                dataCnt <= 4'b0;
            end
        end
    end
    else if(START)begin
        sendEn <= 1;
        uartTxBuff[7:0] <= UARTDATA[7:0];//Copy Data
        UARTTX <= 0;//start bit
    end

end
endmodule

テストベンチ

`timescale 1 ns/ 100 ps
module uart_tx_vlg_tst();
// constants                                           
// general purpose registers
reg eachvec;
// test vector input registers
reg CLK;
reg RST;
reg START;
reg [7:0] UARTDATA;
// wires                                               
wire UARTTX;

// assign statements (if any)                          
uart_tx i1 (
// port map - connection between master ports and signals/registers   
    .CLK(CLK),
    .RST(RST),
    .START(START),
    .UARTDATA(UARTDATA),
    .UARTTX(UARTTX)
);

always #10 CLK = ~CLK;

initial          
begin                                                  
CLK = 0;
RST = 1;
START = 0;
UARTDATA = 8'b0101_1100;

#200 RST = 0;
#200 RST = 1;
#200 START = 1;
#200 START = 0;
#100 UARTDATA = 8'b1100_1001;
#90000 START = 1;
#500 START = 0;
$display("Running testbench");                       
end                                                    

always                                                 
begin                                                                          
@eachvec;                                              
end                                                    
endmodule

気づき

verilog-HDLのソースを変更すると、Modelsimを再度立ち上げ直さないと反映されない。
なにか方法あるのかも?