📄 uart_device.v
字号:
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 + -