UART送信モジュールの設計概要
UART通信の送信モジュールをVerilog HDLで実装する際の主要な構成要素:
/*
標準的なボーレート設定:
4800, 9600, 14400, 115200 bps
50MHzシステムクロック時のカウント値:
(1/4800) * 10^9 /20 -1 = 10416
(1/9600) * 10^9 /20 -1 = 5207
(1/14400) * 10^9 /20 -1 = 3471
(1/115200)* 10^9 /20 -1 = 433
*/
module uart_transmitter
(
input [16:0] baud_rate ,
input clock ,
input reset ,
input [7:0] data_in ,
input transmit_enable ,
output reg serial_out ,
output reg transfer_complete
);
主要機能ブロックの実装
ボーレートカウンタ設定
reg [15:0] max_baud_count;
always @(posedge clock) begin
case(baud_rate)
17'd4800 : max_baud_count <= 16'd10416;
17'd9600 : max_baud_count <= 16'd5207;
17'd14400 : max_baud_count <= 16'd3471;
17'd115200 : max_baud_count <= 16'd433;
default : max_baud_count <= 16'd5207; // デフォルト9600bps
endcase
end
データ転送制御
reg [3:0] bit_position;
reg [15:0] baud_counter;
reg counter_enable;
// ボーレートカウンタ制御
always @(posedge clock or negedge reset) begin
if(!reset) begin
baud_counter <= 16'd0;
counter_enable <= 1'b0;
end
else if(!counter_enable)
baud_counter <= 16'd0;
else if(baud_counter == max_baud_count)
baud_counter <= 16'd0;
else
baud_counter <= baud_counter + 1'b1;
end
シリアルデータ出力
always @(posedge clock or negedge reset) begin
if(!reset)
serial_out <= 1'b1;
else if(!counter_enable)
serial_out <= 1'b1;
else if(baud_counter == 16'd1) begin
case(bit_position)
4'd0: serial_out <= 1'b0; // スタートビット
4'd1: serial_out <= data_buffer[0];
// ... データビット2-8
4'd9: serial_out <= 1'b1; // ストップビット
default: serial_out <= 1'b1;
endcase
end
end
テストベンチ例
module uart_tx_test;
reg [16:0] baud_set = 17'd9600;
reg clk = 1'b1;
reg rst_n = 1'b0;
reg [7:0] test_data;
reg start_signal;
initial begin
forever #10 clk = ~clk;
#21 rst_n = 1'b1;
#40;
// テストデータ送信
for(integer i=0; i<8; i=i+1) begin
@(posedge clk);
test_data = i;
start_signal = 1'b1;
#20 start_signal = 1'b0;
#(5208 * 20 * 10); // 1フレーム分待機
end
$stop;
end
uart_transmitter DUT (
.baud_rate(baud_set),
.clock(clk),
.reset(rst_n),
.data_in(test_data),
.transmit_enable(start_signal),
.serial_out(tx),
.transfer_complete(done)
);
endmodule
シミュレーション波形では、シリアル出力線が初期状態でHIGHになり、スタートビットでLOWに変化することを確認できます。