⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart_device.v

📁 uart协议、实现、验证
💻 V
📖 第 1 页 / 共 2 页
字号:
      begin        if (rx_bit_index == (rx_length + 1))        begin          if (rx_parity_enabled)          begin//            $display("\t\t\t\t\t\t\t(rx_bit_index = %0d) Reading parity bits = %0x", rx_bit_index, rx);          end          else          begin            -> device_received_stop_bit;            rx_stop[rx_stop_bit_index] = rx;            rx_stop_bit_index <= rx_stop_bit_index + 1;          end          rx_parity = rx & rx_parity_enabled;        end        if (rx_bit_index >= (rx_length + 1 + rx_parity_enabled))        begin//          $display("\t\t\t\t\t\t\t(rx_bit_index = %0d) Reading stop bits = %0x", rx_bit_index, rx);          rx_stop[rx_stop_bit_index] = rx;          rx_stop_bit_index <= rx_stop_bit_index + 1;        end      end    end      // Filling the rest of the data with 0    if (rx_length == 5)      rx_data[7:5] = 0;    if (rx_length == 6)      rx_data[7:6] = 0;    if (rx_length == 7)      rx_data[7] = 0;      // Framing error generation    //   When 1 or 1.5 stop bits are used, only first stop bit is checked    rx_framing_error = (rx_stop_bit_1 | rx_stop_bit_1_5) ? ~rx_stop[0] : ~(&rx_stop[1:0]);      // Parity error generation    if (rx_odd_parity)      rx_parity_error = ~(^{rx_data, rx_parity});    else if (rx_even_parity)      rx_parity_error = ^{rx_data, rx_parity};    else if (rx_stick0_parity)      rx_parity_error = rx_parity;    else if (rx_stick1_parity)      rx_parity_error = ~rx_parity;    else      rx_parity_error = 0;  end  // Break detection  always@(posedge rx_clk)  begin    rx_break_detected_q <= rx_break_detected;    if (rx)    begin      rx_break_cnt = 0;         // Reseting counter      rx_break_detected = 0;       // Clearing break detected signal    end    else      rx_break_cnt = rx_break_cnt + 1;    if (rx_break_cnt == rx_break_detection_length * 16 * T_divisor)    begin//      $display("\n(%0t) Break_detected.", $time);      rx_break_detected <= 1;      -> device_detected_rx_break;    end  end    // Writing received data  always@(posedge rx_clk)  begin    if ((rx_packet_end & ~rx_packet_end_q) | (rx_break_detected & ~rx_break_detected_q))    begin      wait (rx | rx_break_detected); // Waiting for "end of cycle detected" or "break to be activated"      // rx_break_detected      //   rx_length      //   rx_parity_enabled      //     rx_odd_parity | rx_even_parity | rx_stick1_parity | rx_stick0_parity      //   rx_stop_bit_1 | rx_stop_bit_1_5 | rx_stop_bit_2      -> device_received_packet;    end  end// UART transmitter//#################  // Initial values for TX  initial  begin    // Default LENGTH    tx_length = 8;    // Default PARITY    tx_odd_parity     = 1'b0;    tx_even_parity    = 1'b0;    tx_stick1_parity  = 1'b0;    tx_stick0_parity  = 1'b0;    tx_parity_enabled = 1'b0;    // Default CORRECT PARITY    tx_parity_wrong = 1'b0;    // Default CORRECT FRAME    tx_framing_wrong = 1'b0;    tx_framing_err        = 0;    tx_framing_glitch_err = 0;    // Default NO GLITCH    tx_glitch_num = 24'h0;    // Default NO BREAK    tx_break_enable = 1'b0;    tx_break_num = 16'h0;  end  // Counter for TX glitch generation  always@(posedge tx_clk or posedge start_tx_glitch_cnt)  begin    if (start_tx_glitch_cnt)    begin      tx_glitch_cnt <= tx_glitch_cnt + 1;      if (tx_glitch_cnt == ((tx_glitch_num - 1) * T_divisor))        tx_glitch = 1'b1;      else if (tx_glitch_cnt == (tx_glitch_num * T_divisor))      begin        tx_glitch = 1'b0;        start_tx_glitch_cnt = 1'b0;      end    end    else      tx_glitch_cnt <= 0;  end  // Break setting & break counter  always@(posedge tx_clk)  begin    if (tx_break_enable && (tx_break_cnt == (tx_break_num * T_divisor)))    begin      start_tx_break_cnt = 0;    end    else if (start_tx_break_cnt)    begin      tx_break_cnt = tx_break_cnt + 1;      tx_break = 1;    end    else    begin      tx_break_cnt = 0;      tx_break = 0;    end  end    // Sending packets  task send_packet;    input          tx_random_i;    input   [7:0]  tx_data_i;    input          num_of_tx_data_i;    reg     [7:0]  tx_data;    reg            tx_parity_xor;    integer        tx_bit_index;    integer        num_of_tx_data;    reg            last_tx_data;  begin    // SEVERE ERROR    if (// WRONG combinations of parameters for testing         ((T_clk_delay != 0) && (tx_parity_wrong || tx_framing_wrong))               ||         ((T_clk_delay != 0) && (tx_glitch_num != 0))                                ||         ((T_clk_delay != 0) && (tx_break_enable))                                   ||         ((tx_parity_wrong || tx_framing_wrong) && (tx_glitch_num != 0))             ||         ((tx_parity_wrong || tx_framing_wrong) && (tx_break_enable))                ||         ((tx_glitch_num != 0) && (tx_break_enable))                                 ||         (tx_glitch_num > ((tx_length + 2'h2 + tx_parity_enabled) * 16 * T_divisor)) || // with STOP bit//        (tx_glitch_num > ((tx_length + 2'h1 + tx_parity_enabled) * 16 * T_divisor)) || // without STOP bit        // WRONG input parameters        (num_of_tx_data_i == 0)                                                     ||         ((num_of_tx_data_i > 1) && tx_break_enable)                                        )    begin      `SEVERE_ERROR("WRONG combination of parameters for testing UART receiver");    end        for (num_of_tx_data = 0;          num_of_tx_data < num_of_tx_data_i;          num_of_tx_data = (num_of_tx_data + 1'b1))    begin          if (num_of_tx_data == (num_of_tx_data_i - 1'b1))        last_tx_data = 1'b1;      else        last_tx_data = 0;          // TX data      if (~tx_random_i)        tx_data = tx_data_i;      else        tx_data = {$random}%256; // 0..255          // Sending start bit      @(posedge tx_clk_divided);      tx = 0;      if (tx_glitch_num > 0)        start_tx_glitch_cnt = 1;            // enabling tx_glitch generation      if (tx_break_enable)        start_tx_break_cnt = 1;       // Start counter that counts break tx_length      // Wait for almost 1 bit      #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period      #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period          // Sending tx_data bits      for (tx_bit_index = 0; tx_bit_index < tx_length; tx_bit_index = tx_bit_index + 1)      begin        @(posedge tx_clk_divided);        tx = tx_data[tx_bit_index];      end      // Wait for almost 1 bit      #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period      #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period      sent_data = tx_data;          // Calculating parity      if(tx_length == 5)      begin        tx_parity_xor = ^tx_data[4:0];      end      else if(tx_length == 6)      begin        tx_parity_xor = ^tx_data[5:0];      end      else if(tx_length == 7)      begin        tx_parity_xor = ^tx_data[6:0];      end      else if(tx_length == 8)      begin        tx_parity_xor = ^tx_data[7:0];      end      else        $display("WRONG length of TX data packet");          // Sending parity bit      if (tx_parity_enabled)      begin        @(posedge tx_clk_divided);        if (tx_odd_parity)          tx = tx_parity_wrong ^ (~tx_parity_xor);        else if (tx_even_parity)          tx = tx_parity_wrong ^ tx_parity_xor;        else if (tx_stick1_parity)          tx = tx_parity_wrong ^ 1;        else if (tx_stick0_parity)          tx = tx_parity_wrong ^ 0;        // Wait for almost 1 bit        #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period        #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period      end          // Sending stop bit      if (~tx_framing_wrong ||           (tx_glitch_num != ((((tx_length + 2'h2 + tx_parity_enabled) * 2) - 1'b1) * 8 * T_divisor)))      begin        @(posedge tx_clk_divided);        tx = 1;        // Wait for almost 1 bit        #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period        #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period        -> device_sent_packet;        @(sent_packet_received);      end      else if (~tx_framing_wrong ||                (tx_glitch_num == ((((tx_length + 2'h2 + tx_parity_enabled) * 2) - 1'b1) * 8 * T_divisor)))      begin        @(posedge tx_clk_divided);        tx = 1;        // Wait for 1 bit        @(posedge tx_clk_divided); // this will be like 2. stop bit        -> device_sent_packet;        @(sent_packet_received);      end      else if (tx_framing_wrong && last_tx_data)      begin        @(posedge tx_clk_divided);        // Wrong stop | start bit        tx = 0;        @(posedge tx_clk_divided);        -> device_sent_packet;        @(sent_packet_received);        tx_framing_wrong = 0;        // TX data        tx = 1;        tx_data = 8'hFF;        // Sending tx_data bits        for (tx_bit_index = 0; tx_bit_index < tx_length; tx_bit_index = tx_bit_index + 1)        begin          @(posedge tx_clk_divided);          tx = tx_data[tx_bit_index];        end        // Wait for almost 1 bit        #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period        #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period          sent_data = tx_data;              // Calculating parity        if(tx_length == 5)        begin          tx_parity_xor = ^tx_data[4:0];        end        else if(tx_length == 6)        begin          tx_parity_xor = ^tx_data[5:0];        end        else if(tx_length == 7)        begin          tx_parity_xor = ^tx_data[6:0];        end        else if(tx_length == 8)        begin          tx_parity_xor = ^tx_data[7:0];        end        else          $display("WRONG length of TX data packet");              // Sending parity bit        if (tx_parity_enabled)        begin          @(posedge tx_clk_divided);          if (tx_odd_parity)            tx = tx_parity_wrong ^ (~tx_parity_xor);          else if (tx_even_parity)            tx = tx_parity_wrong ^ tx_parity_xor;          else if (tx_stick1_parity)            tx = tx_parity_wrong ^ 1;          else if (tx_stick0_parity)            tx = tx_parity_wrong ^ 0;          // Wait for almost 1 bit          #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period          #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period        end                // Stop bit        @(posedge tx_clk_divided);        tx = 1;        // Wait for almost 1 bit        #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period        #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period        -> device_sent_packet;        @(sent_packet_received);        tx_framing_wrong = 1'b1;      end      else if (last_tx_data)      begin        @(posedge tx_clk_divided);        -> device_sent_packet;        @(sent_packet_received);      end    end  end  endtask // send_packetendmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -