krzys_h

Hello world V2

Jul 29th, 2019
416
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. `timescale 1ns / 1ps
  2.  
  3. function integer clogb2;
  4.     input [31:0] value;
  5.     begin
  6.         value = value - 1;
  7.         for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) begin
  8.             value = value >> 1;
  9.         end
  10.     end
  11. endfunction
  12.  
  13. // UART clock generator - runs the UART clock which ticks uart_clk once after every bit
  14. // Additionally, uart_clk_halfbit is triggered in the middle of the cycle (for rx probing)
  15. // The clock is synchronized to the rising edge of the enable input
  16. module uart_clkgen #(parameter baudrate = 9600, parameter clock_rate = 100000000) (
  17.     input CLK,
  18.     input enable,
  19.     output uart_clk,
  20.     output uart_clk_halfbit
  21. );
  22.  
  23.     localparam clks_per_bit = clock_rate / baudrate;
  24.     localparam counter_len = clogb2(clks_per_bit);
  25.    
  26.     reg [counter_len:0] clock_counter;
  27.     assign uart_clk = (clock_counter == clks_per_bit);
  28.     assign uart_clk_halfbit = (clock_counter == clks_per_bit/2);
  29.    
  30.     always @(posedge CLK)
  31.     begin
  32.         if (enable && ~uart_clk)
  33.             clock_counter <= clock_counter + 1;
  34.         else
  35.             clock_counter <= 0;
  36.     end
  37.  
  38. endmodule
  39.  
  40. // UART transmitter module
  41. // Put the data in, set tx_req and trigger the clock to start the transmission
  42. // The input byte is latched internally
  43. // tx_done is raised for a single clock cycle after the transmission is finished
  44. // tx_ready is high when the module is not transmissing (i.e. ready to accept the next byte)
  45. module uart_tx #(parameter baudrate = 9600, parameter clock_rate = 100000000) (
  46.     input CLK,
  47.     output tx,
  48.    
  49.     input [7:0] data,
  50.     input tx_req,
  51.     output tx_done,
  52.     output tx_ready
  53. );
  54.  
  55.     localparam STATE_IDLE = 0;
  56.     localparam STATE_STARTBIT = 1;
  57.     localparam STATE_DATA = 2;
  58.     localparam STATE_STOPBIT = 3;
  59.    
  60.     reg [1:0] state = STATE_IDLE;
  61.     reg [2:0] current_bit;
  62.     reg [7:0] send_buffer;
  63.     wire uart_clk;
  64.    
  65.     uart_clkgen #(
  66.         .baudrate(baudrate),
  67.         .clock_rate(clock_rate)
  68.     ) clkgen(
  69.         .CLK(CLK),
  70.         .enable(state != STATE_IDLE),
  71.         .uart_clk(uart_clk)
  72.     );
  73.    
  74.     always @(posedge CLK)
  75.     begin
  76.         case(state)
  77.             STATE_IDLE:
  78.                 if (tx_req)
  79.                 begin
  80.                     send_buffer <= data;
  81.                     state <= STATE_STARTBIT;
  82.                 end
  83.             STATE_STARTBIT:
  84.                 if (uart_clk)
  85.                 begin
  86.                     current_bit <= 0;
  87.                     state <= STATE_DATA;
  88.                 end
  89.             STATE_DATA:
  90.                 if (uart_clk)
  91.                 begin
  92.                     if (current_bit == 7)
  93.                         state <= STATE_STOPBIT;
  94.                     else
  95.                         current_bit <= current_bit + 1;
  96.                 end
  97.             STATE_STOPBIT:
  98.                 if (uart_clk)
  99.                 begin
  100.                     state <= STATE_IDLE;
  101.                 end
  102.         endcase
  103.     end
  104.    
  105.     assign tx = (state == STATE_IDLE    ) ? 1 :
  106.                     (state == STATE_STARTBIT) ? 0 :
  107.                     (state == STATE_DATA    ) ? send_buffer[current_bit] :
  108.                     (state == STATE_STOPBIT ) ? 1 :
  109.                     1'bz;
  110.     assign tx_ready = (state == STATE_IDLE);
  111.     assign tx_done = (state == STATE_STOPBIT && uart_clk);
  112.  
  113. endmodule
  114.  
  115. // Hello world - transmits the string "Hello world" over UART every 1 second
  116. module helloWorld(
  117.     input CLK,
  118.     inout [3:3] IO_P1
  119. );
  120.  
  121.     parameter [7:0] str[0:13] = "Hello world!\r\n";
  122.    
  123.     reg [clogb2(100000000):0] counter = 0;
  124.     reg [7:0] num = 0;
  125.     reg tx_req = 1;
  126.  
  127.     uart_tx tx(
  128.         .tx(IO_P1[3]),
  129.         .CLK(CLK),
  130.         .data(str[num]),
  131.         .tx_req(tx_req),
  132.         .tx_done(tx_done)
  133.     );
  134.  
  135.     always @(posedge CLK)
  136.     begin
  137.         // Every 1 second, start the transmission
  138.         if (counter == 100000000)
  139.         begin
  140.             counter <= 0;
  141.             num <= 0;
  142.             tx_req <= 1;
  143.         end
  144.         else
  145.             counter <= counter + 1;
  146.        
  147.         // When transmission is done and we have more bytes to transmit,
  148.         // immediately set tx_req again to transmit the next byte
  149.         if (tx_done && num != 13)
  150.         begin
  151.             tx_req <= 1;
  152.             num <= num + 1;
  153.         end
  154.        
  155.         // After one clock cycle, tx_req should return to low state
  156.         if (tx_req)
  157.         begin
  158.             tx_req <= 0;
  159.         end
  160.     end
  161.  
  162. endmodule
  163.  
  164. /*
  165. module uart_tx_tb();
  166.     reg CLK = 0;
  167.     always
  168.         #1 CLK <= !CLK;
  169.  
  170.     wire tx;
  171.     reg [7:0] tx_data;
  172.     reg tx_req = 0;
  173.     wire tx_ready;
  174.     wire tx_done;
  175.    
  176.     uart_tx uart_tx_instance(
  177.         .tx(tx),
  178.         .CLK(CLK),
  179.         .data(tx_data),
  180.         .tx_req(tx_req),
  181.         .tx_ready(tx_ready),
  182.         .tx_done(tx_done)
  183.     );
  184.    
  185.     initial
  186.     begin
  187.         @(posedge CLK);
  188.         @(posedge CLK);
  189.         tx_req <= 1;
  190.         tx_data <= 8'b10101001;
  191.         @(posedge CLK);
  192.         tx_req <= 0;
  193.         @(posedge tx_done);
  194.         @(posedge CLK);
  195.         @(posedge CLK);
  196.         $finish;
  197.     end
  198.  
  199. endmodule
  200. */
Add Comment
Please, Sign In to add comment