KRUTOMER 0 January 19, 2022 Posted January 19, 2022 · Report post Описываю поведение простого UART-передатчика на Verilog в среде Xiling Vivado 2018.2. При присваивании D-триггеру значения с входного порта, он переходит в Z-состояние. Также при попытке присвоить этот сигнал цепи через оператор непрерывного присваивания assign, цепь также принимает высокоимпедансное состояние. В чем может быть причина такого поведения/симуляции, и как это можно исправить? Описание модуля следующее: Скрытый текст `timescale 1ns / 100ps module UART_rx #(parameter FREQ = 24_000_000, BAUD_RATE = 9600) ( input wire clk, //reset, input wire DATA_serial, output reg data_bit, output reg data_bit2, output reg [2:0] STATE, output reg [11:0] clk_counter, output reg done_tick = 0, output wire [7:0] DATA_byte ); //signal declaration //reg [11:0] clk_counter = 0; //reg data_bit, data_bit2; reg [2:0] bit_index = 0; reg [7:0] byte_bit = 0; //reg [2:0] STATE = 0; //dowble register body always @(posedge clk) begin data_bit2 <= DATA_serial; data_bit <= data_bit2; end //state declaration localparam [2:0] IDLE = 3'b000, START_BIT = 3'b001, DATA_TRANSFER = 3'b010, STOP_BIT = 3'b011, CLEAN_UP = 3'b100; //------------FSM BODY--------------- always @(posedge clk) begin case (STATE) IDLE: begin //waiting start_bit done_tick <= 0; clk_counter <= 0; bit_index <= 0; if (data_bit == 0) STATE <= START_BIT; else STATE <= IDLE; end START_BIT: begin //check the midle of start_bit done_tick <= 0; clk_counter <= 0; bit_index <= 0; if (clk_counter == ((FREQ/2/BAUD_RATE)-1)) if (data_bit == 0) begin clk_counter <= 0; //midle of input_bit duration STATE <= DATA_TRANSFER; end else STATE <= IDLE; else begin clk_counter <= clk_counter + 1; STATE <= START_BIT; end end DATA_TRANSFER: begin // receive 8 bit of data done_tick <= 0; bit_index <= 0; if (clk_counter < ((FREQ/BAUD_RATE)-1)) begin clk_counter <= clk_counter + 1; STATE <= DATA_TRANSFER; end else begin clk_counter <= 0; byte_bit[bit_index] <= data_bit; if (bit_index < 7) begin bit_index <= bit_index + 1; STATE <= DATA_TRANSFER; end else begin bit_index <= 0; STATE <= STOP_BIT; end end end STOP_BIT: begin // receive stop-bit if (clk_counter < ((FREQ/BAUD_RATE)-1)) begin clk_counter <= clk_counter + 1; STATE <= STOP_BIT; end else begin done_tick <= 1; clk_counter <= 0; STATE <= CLEAN_UP; end end CLEAN_UP: begin //waiting 1 clk cycle done_tick <= 0; STATE <= IDLE; end default: STATE <= IDLE; endcase end assign DATA_byte = byte_bit; endmodule Quote Share this post Link to post Share on other sites More sharing options...
Raven 0 January 19, 2022 Posted January 19, 2022 · Report post А код тестбенча можете привести? Quote Share this post Link to post Share on other sites More sharing options...
=AK= 6 January 19, 2022 Posted January 19, 2022 · Report post 2 hours ago, KRUTOMER said: Описываю поведение простого UART-передатчика на Verilog в среде Xiling Vivado 2018.2. При присваивании D-триггеру значения с входного порта, он переходит в Z-состояние. Также при попытке присвоить этот сигнал цепи через оператор непрерывного присваивания assign, цепь также принимает высокоимпедансное состояние. В чем может быть причина такого поведения/симуляции, и как это можно исправить? Причина может быть в метастабильности Quote Share this post Link to post Share on other sites More sharing options...
RobFPGA 10 January 19, 2022 Posted January 19, 2022 · Report post 3 minutes ago, =AK= said: Причина может быть в том, что входной сигнал и клок находятся в разных time domains. В симуляторе нет понятия мета-стабильность. Скорее всего проблемы в самой логике модуля или TB. Quote Share this post Link to post Share on other sites More sharing options...
Obam 13 January 19, 2022 Posted January 19, 2022 · Report post Описываю поведение простого UART-передатчика... // receive 8 bit of data Может для начала в schematic-е? Для ясности ;-) Quote Share this post Link to post Share on other sites More sharing options...
KRUTOMER 0 January 20, 2022 Posted January 20, 2022 · Report post 8 часов назад, Raven сказал: А код тестбенча можете привести? Вот код самого тестбенча: `timescale 1ns / 1ps module UART_test; reg clk; //reset; reg DATA_serial; wire done_tick, data_bit, data_bit2; wire [2:0] STATE; wire [7:0] DATA_byte; wire [11:0] clk_counter; UART_rx UART_uut (.clk(clk),/* .reset(reset),*/ .done_tick(done_tick), .DATA_byte(DATA_byte), .data_bit(data_bit), .data_bit2(data_bit2), .STATE(STATE), .clk_counter(clk_counter)); initial begin clk = 0; //reset = 1; DATA_serial = 1'b1; end always #40 clk = ~clk; initial begin //#100 reset = 0; #10000 #100_000 DATA_serial = 1'b1; #100_000 DATA_serial = 1'b0; //start-bit #100_000 DATA_serial = 1'b1; //0 #100_000 DATA_serial = 1'b0; //1 #100_000 DATA_serial = 1'b0; //2 #100_000 DATA_serial = 1'b0; //3 #100_000 DATA_serial = 1'b0; //4 #100_000 DATA_serial = 1'b0; //5 #100_000 DATA_serial = 1'b0; //6 #100_000 DATA_serial = 1'b0; //7 #100_000 DATA_serial = 1'b1; //stop-bit #100_000 $stop; end endmodule 7 часов назад, Obam сказал: Может для начала в schematic-е? Для ясности ;-) schematic.pdf Quote Share this post Link to post Share on other sites More sharing options...
RobFPGA 10 January 20, 2022 Posted January 20, 2022 · Report post 12 hours ago, KRUTOMER said: Описание модуля следующее: 1 hour ago, KRUTOMER said: Вот код самого тестбенча: Если уж в модуле UART есть вход DATA_serial то почему в TB вы его не подключаете в модуль? Висящий в "воздухе" вход имеет неопределённой состояние которое и распространяется по логике модуля. Quote Share this post Link to post Share on other sites More sharing options...
KRUTOMER 0 January 20, 2022 Posted January 20, 2022 · Report post 24 минуты назад, RobFPGA сказал: Если уж в модуле UART есть вход DATA_serial то почему в TB вы его не подключаете в модуль? Висящий в "воздухе" вход имеет неопределённой состояние которое и распространяется по логике модуля. Да, и вправду по невнимательности не добавил DATA_serial и инстанс. Сбасибо большое Quote Share this post Link to post Share on other sites More sharing options...
new123 0 January 20, 2022 Posted January 20, 2022 · Report post 11 hours ago, RobFPGA said: В симуляторе нет понятия мета-стабильность. может придираюсь к словам, я же сейчас в timing simulation засел. Там если симулятор без спец ключа запустить, то при первом же слаке сигнал впадает в X. Не знаю, называется ли это мета-стабильность. Ну и понятно, что тут не этот случай, просто к слову Quote Share this post Link to post Share on other sites More sharing options...
RobFPGA 10 January 20, 2022 Posted January 20, 2022 · Report post 1 minute ago, new123 said: может придираюсь к словам, я же сейчас в timing simulation засел. Там если симулятор без спец ключа запустить, то при первом же слаке сигнал впадает в X. Не знаю, называется ли это мета-стабильность В симе, при желании, можно симулировать поведение триггера при условиях возникновения мета-стабильности. Но для этого нужны специальные модели. Как раз для этого и служат библиотеки примитивов которые используются для timing simulation. Но в функциональной симуляции (и вообще в симе) как таковой мета-стабильности нет, так как значение триггеру присваивается за 0 время. Quote Share this post Link to post Share on other sites More sharing options...
Obam 13 January 21, 2022 Posted January 21, 2022 · Report post Так всё-таки это приёмник УАППа (но до чего hardware "жирный") и проблема разрешиась? Quote Share this post Link to post Share on other sites More sharing options...
KRUTOMER 0 January 24, 2022 Posted January 24, 2022 (edited) · Report post Еще раз спасибо большое всем, кто помог решить проблему и написал код ревью на мой UART-приемник. Все-таки решил чуть переписать модуль по заветам Понг П. Чу, а именно конечный автомат Модуль: `timescale 1ns / 100ps module UART_receiver #(parameter FREQ = 24_000_000, BAUD_RATE = 9600) ( input wire clk, //reset, input wire DATA_serial, output reg data_bit = 0, output reg data_bit2 = 0, output reg [2:0] STATE_reg = 0, output reg [11:0] clk_counter_reg = 0, output reg [2:0] bit_index_reg = 0, output reg done_tick = 0, output wire [7:0] DATA_byte ); //signal declaration //reg [11:0] clk_counter_reg; reg [11:0] clk_counter_next; //reg data_bit, data_bit2; //reg [2:0] bit_index_reg; reg [2:0] bit_index_next; reg [7:0] byte_bit = 0; //reg [2:0] STATE_reg; reg [2:0] STATE_next; //dowble register body always @(posedge clk) begin data_bit2 <= DATA_serial; data_bit <= data_bit2; STATE_reg <= STATE_next; clk_counter_reg <= clk_counter_next; bit_index_reg <= bit_index_next; end //state declaration localparam [2:0] IDLE = 3'b000, START_BIT = 3'b001, DATA_TRANSFER = 3'b010, STOP_BIT = 3'b011, DONE = 3'b100; //------------FSM BODY--------------- always @* begin done_tick = 0; clk_counter_next = clk_counter_reg; bit_index_next = bit_index_reg; STATE_next = STATE_reg; case (STATE_reg) IDLE: begin //waiting start_bit if (data_bit == 0) STATE_next = START_BIT; else STATE_next = IDLE; end START_BIT: begin //check the midle of start_bit if (clk_counter_next == ((FREQ/2/BAUD_RATE)-1)) if (data_bit == 0) begin clk_counter_next = 0; //midle of input_bit duration STATE_next = DATA_TRANSFER; end else STATE_next = IDLE; else begin clk_counter_next = clk_counter_reg + 1; STATE_next = START_BIT; end end DATA_TRANSFER: begin // receive 8 bit of data if (clk_counter_next < ((FREQ/BAUD_RATE)-1)) begin clk_counter_next = clk_counter_reg + 1; STATE_next = DATA_TRANSFER; end else begin clk_counter_next = 0; byte_bit[bit_index_next] = data_bit; if (bit_index_next < 7) begin bit_index_next = bit_index_reg + 1; STATE_next = DATA_TRANSFER; end else begin bit_index_next = 0; STATE_next = STOP_BIT; end end end STOP_BIT: begin // receive stop-bit if (clk_counter_next < ((FREQ/BAUD_RATE)-1)) begin clk_counter_next = clk_counter_reg + 1; STATE_next = STOP_BIT; end else begin // done_tick = 1; clk_counter_next = 0; STATE_next = DONE; end end DONE: begin //waiting 1 clk cycle done_tick = 1; STATE_next = IDLE; end default: STATE_next = IDLE; endcase end assign DATA_byte = byte_bit; endmodule Тестбенч: `timescale 1ns / 1ps module UART_test; reg clk; //reset; reg DATA_serial; wire done_tick, data_bit, data_bit2; wire [2:0] bit_index; wire [2:0] STATE; wire [7:0] DATA_byte; wire [11:0] clk_counter; UART_receiver UART_uut (.clk(clk),/* .reset(reset),*/ .done_tick(done_tick), .DATA_byte(DATA_byte), .DATA_serial(DATA_serial), .data_bit(data_bit), .data_bit2(data_bit2), .STATE_reg(STATE), .clk_counter_reg(clk_counter), .bit_index_reg(bit_index)); initial begin clk = 0; //reset = 1; DATA_serial = 1'b1; end always #40 clk = ~clk; initial begin //#100 reset = 0; #200_000 #200_000 DATA_serial = 1'b1; #200_000 DATA_serial = 1'b0; //start-bit #200_000 DATA_serial = 1'b0; //0 #200_000 DATA_serial = 1'b1; //1 #200_000 DATA_serial = 1'b1; //2 #200_000 DATA_serial = 1'b0; //3 #200_000 DATA_serial = 1'b0; //4 #200_000 DATA_serial = 1'b1; //5 #200_000 DATA_serial = 1'b0; //6 #200_000 DATA_serial = 1'b0; //7 #200_000 DATA_serial = 1'b1; //stop-bit #200_000 $stop; end 22.01.2022 в 01:25, Obam сказал: Так всё-таки это приёмник УАППа (но до чего hardware "жирный") и проблема разрешиась? Просто для симуляции сделал дополнительные выходы Edited January 24, 2022 by KRUTOMER Quote Share this post Link to post Share on other sites More sharing options...
RobFPGA 10 January 24, 2022 Posted January 24, 2022 · Report post 2 hours ago, KRUTOMER said: Все-таки решил чуть переписать модуль по заветам Понг П. Чу, а именно конечный автомат Модуль: Совет - лучше вставлять код в фрейм Code <>, так не слетает форматирование. А если код длинный, то заодно и в фрейм Spoiler чтобы была удобнее навигация по топикам. Quote Share this post Link to post Share on other sites More sharing options...