KRUTOMER 0 Posted January 19 · 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
Raven 0 Posted January 19 · Report post А код тестбенча можете привести? Quote Ответить с цитированием Share this post Link to post Share on other sites
=AK= 0 Posted January 19 · 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
RobFPGA 0 Posted January 19 · Report post 3 minutes ago, =AK= said: Причина может быть в том, что входной сигнал и клок находятся в разных time domains. В симуляторе нет понятия мета-стабильность. Скорее всего проблемы в самой логике модуля или TB. Quote Ответить с цитированием Share this post Link to post Share on other sites
Obam 0 Posted January 19 · Report post Описываю поведение простого UART-передатчика... // receive 8 bit of data Может для начала в schematic-е? Для ясности ;-) Quote Ответить с цитированием Share this post Link to post Share on other sites
KRUTOMER 0 Posted January 20 · 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
RobFPGA 0 Posted January 20 · 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
KRUTOMER 0 Posted January 20 · Report post 24 минуты назад, RobFPGA сказал: Если уж в модуле UART есть вход DATA_serial то почему в TB вы его не подключаете в модуль? Висящий в "воздухе" вход имеет неопределённой состояние которое и распространяется по логике модуля. Да, и вправду по невнимательности не добавил DATA_serial и инстанс. Сбасибо большое Quote Ответить с цитированием Share this post Link to post Share on other sites
new123 0 Posted January 20 · Report post 11 hours ago, RobFPGA said: В симуляторе нет понятия мета-стабильность. может придираюсь к словам, я же сейчас в timing simulation засел. Там если симулятор без спец ключа запустить, то при первом же слаке сигнал впадает в X. Не знаю, называется ли это мета-стабильность. Ну и понятно, что тут не этот случай, просто к слову Quote Ответить с цитированием Share this post Link to post Share on other sites
RobFPGA 0 Posted January 20 · Report post 1 minute ago, new123 said: может придираюсь к словам, я же сейчас в timing simulation засел. Там если симулятор без спец ключа запустить, то при первом же слаке сигнал впадает в X. Не знаю, называется ли это мета-стабильность В симе, при желании, можно симулировать поведение триггера при условиях возникновения мета-стабильности. Но для этого нужны специальные модели. Как раз для этого и служат библиотеки примитивов которые используются для timing simulation. Но в функциональной симуляции (и вообще в симе) как таковой мета-стабильности нет, так как значение триггеру присваивается за 0 время. Quote Ответить с цитированием Share this post Link to post Share on other sites
Obam 0 Posted January 21 · Report post Так всё-таки это приёмник УАППа (но до чего hardware "жирный") и проблема разрешиась? Quote Ответить с цитированием Share this post Link to post Share on other sites
KRUTOMER 0 Posted January 24 (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 by KRUTOMER Quote Ответить с цитированием Share this post Link to post Share on other sites
RobFPGA 0 Posted January 24 · Report post 2 hours ago, KRUTOMER said: Все-таки решил чуть переписать модуль по заветам Понг П. Чу, а именно конечный автомат Модуль: Совет - лучше вставлять код в фрейм Code <>, так не слетает форматирование. А если код длинный, то заодно и в фрейм Spoiler чтобы была удобнее навигация по топикам. Quote Ответить с цитированием Share this post Link to post Share on other sites