Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- `timescale 1ns / 1ps
- function integer clogb2;
- input [31:0] value;
- begin
- value = value - 1;
- for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) begin
- value = value >> 1;
- end
- end
- endfunction
- // UART clock generator - runs the UART clock which ticks uart_clk once after every bit
- // Additionally, uart_clk_halfbit is triggered in the middle of the cycle (for rx probing)
- // The clock is synchronized to the rising edge of the enable input
- module uart_clkgen #(parameter baudrate = 9600, parameter clock_rate = 100000000) (
- input CLK,
- input enable,
- output uart_clk,
- output uart_clk_halfbit
- );
- localparam clks_per_bit = clock_rate / baudrate;
- localparam counter_len = clogb2(clks_per_bit);
- reg [counter_len:0] clock_counter;
- assign uart_clk = (clock_counter == clks_per_bit);
- assign uart_clk_halfbit = (clock_counter == clks_per_bit/2);
- always @(posedge CLK)
- begin
- if (enable && ~uart_clk)
- clock_counter <= clock_counter + 1;
- else
- clock_counter <= 0;
- end
- endmodule
- // UART transmitter module
- // Put the data in, set tx_req and trigger the clock to start the transmission
- // The input byte is latched internally
- // tx_done is raised for a single clock cycle after the transmission is finished
- // tx_ready is high when the module is not transmissing (i.e. ready to accept the next byte)
- module uart_tx #(parameter baudrate = 9600, parameter clock_rate = 100000000) (
- input CLK,
- output tx,
- input [7:0] data,
- input tx_req,
- output tx_done,
- output tx_ready
- );
- localparam STATE_IDLE = 0;
- localparam STATE_STARTBIT = 1;
- localparam STATE_DATA = 2;
- localparam STATE_STOPBIT = 3;
- reg [1:0] state = STATE_IDLE;
- reg [2:0] current_bit;
- reg [7:0] send_buffer;
- wire uart_clk;
- uart_clkgen #(
- .baudrate(baudrate),
- .clock_rate(clock_rate)
- ) clkgen(
- .CLK(CLK),
- .enable(state != STATE_IDLE),
- .uart_clk(uart_clk)
- );
- always @(posedge CLK)
- begin
- case(state)
- STATE_IDLE:
- if (tx_req)
- begin
- send_buffer <= data;
- state <= STATE_STARTBIT;
- end
- STATE_STARTBIT:
- if (uart_clk)
- begin
- current_bit <= 0;
- state <= STATE_DATA;
- end
- STATE_DATA:
- if (uart_clk)
- begin
- if (current_bit == 7)
- state <= STATE_STOPBIT;
- else
- current_bit <= current_bit + 1;
- end
- STATE_STOPBIT:
- if (uart_clk)
- begin
- state <= STATE_IDLE;
- end
- endcase
- end
- assign tx = (state == STATE_IDLE ) ? 1 :
- (state == STATE_STARTBIT) ? 0 :
- (state == STATE_DATA ) ? send_buffer[current_bit] :
- (state == STATE_STOPBIT ) ? 1 :
- 1'bz;
- assign tx_ready = (state == STATE_IDLE);
- assign tx_done = (state == STATE_STOPBIT && uart_clk);
- endmodule
- // Hello world - transmits the string "Hello world" over UART every 1 second
- module helloWorld(
- input CLK,
- inout [3:3] IO_P1
- );
- parameter [7:0] str[0:13] = "Hello world!\r\n";
- reg [clogb2(100000000):0] counter = 0;
- reg [7:0] num = 0;
- reg tx_req = 1;
- uart_tx tx(
- .tx(IO_P1[3]),
- .CLK(CLK),
- .data(str[num]),
- .tx_req(tx_req),
- .tx_done(tx_done)
- );
- always @(posedge CLK)
- begin
- // Every 1 second, start the transmission
- if (counter == 100000000)
- begin
- counter <= 0;
- num <= 0;
- tx_req <= 1;
- end
- else
- counter <= counter + 1;
- // When transmission is done and we have more bytes to transmit,
- // immediately set tx_req again to transmit the next byte
- if (tx_done && num != 13)
- begin
- tx_req <= 1;
- num <= num + 1;
- end
- // After one clock cycle, tx_req should return to low state
- if (tx_req)
- begin
- tx_req <= 0;
- end
- end
- endmodule
- /*
- module uart_tx_tb();
- reg CLK = 0;
- always
- #1 CLK <= !CLK;
- wire tx;
- reg [7:0] tx_data;
- reg tx_req = 0;
- wire tx_ready;
- wire tx_done;
- uart_tx uart_tx_instance(
- .tx(tx),
- .CLK(CLK),
- .data(tx_data),
- .tx_req(tx_req),
- .tx_ready(tx_ready),
- .tx_done(tx_done)
- );
- initial
- begin
- @(posedge CLK);
- @(posedge CLK);
- tx_req <= 1;
- tx_data <= 8'b10101001;
- @(posedge CLK);
- tx_req <= 0;
- @(posedge tx_done);
- @(posedge CLK);
- @(posedge CLK);
- $finish;
- end
- endmodule
- */
Add Comment
Please, Sign In to add comment