KRUTOMER 0 19 января, 2022 Опубликовано 19 января, 2022 · Жалоба Описываю поведение простого 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Raven 11 19 января, 2022 Опубликовано 19 января, 2022 · Жалоба А код тестбенча можете привести? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=AK= 18 19 января, 2022 Опубликовано 19 января, 2022 · Жалоба 2 hours ago, KRUTOMER said: Описываю поведение простого UART-передатчика на Verilog в среде Xiling Vivado 2018.2. При присваивании D-триггеру значения с входного порта, он переходит в Z-состояние. Также при попытке присвоить этот сигнал цепи через оператор непрерывного присваивания assign, цепь также принимает высокоимпедансное состояние. В чем может быть причина такого поведения/симуляции, и как это можно исправить? Причина может быть в метастабильности Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 34 19 января, 2022 Опубликовано 19 января, 2022 · Жалоба 3 minutes ago, =AK= said: Причина может быть в том, что входной сигнал и клок находятся в разных time domains. В симуляторе нет понятия мета-стабильность. Скорее всего проблемы в самой логике модуля или TB. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 19 января, 2022 Опубликовано 19 января, 2022 · Жалоба Описываю поведение простого UART-передатчика... // receive 8 bit of data Может для начала в schematic-е? Для ясности ;-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRUTOMER 0 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 34 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба 12 hours ago, KRUTOMER said: Описание модуля следующее: 1 hour ago, KRUTOMER said: Вот код самого тестбенча: Если уж в модуле UART есть вход DATA_serial то почему в TB вы его не подключаете в модуль? Висящий в "воздухе" вход имеет неопределённой состояние которое и распространяется по логике модуля. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRUTOMER 0 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба 24 минуты назад, RobFPGA сказал: Если уж в модуле UART есть вход DATA_serial то почему в TB вы его не подключаете в модуль? Висящий в "воздухе" вход имеет неопределённой состояние которое и распространяется по логике модуля. Да, и вправду по невнимательности не добавил DATA_serial и инстанс. Сбасибо большое Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба 11 hours ago, RobFPGA said: В симуляторе нет понятия мета-стабильность. может придираюсь к словам, я же сейчас в timing simulation засел. Там если симулятор без спец ключа запустить, то при первом же слаке сигнал впадает в X. Не знаю, называется ли это мета-стабильность. Ну и понятно, что тут не этот случай, просто к слову Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 34 20 января, 2022 Опубликовано 20 января, 2022 · Жалоба 1 minute ago, new123 said: может придираюсь к словам, я же сейчас в timing simulation засел. Там если симулятор без спец ключа запустить, то при первом же слаке сигнал впадает в X. Не знаю, называется ли это мета-стабильность В симе, при желании, можно симулировать поведение триггера при условиях возникновения мета-стабильности. Но для этого нужны специальные модели. Как раз для этого и служат библиотеки примитивов которые используются для timing simulation. Но в функциональной симуляции (и вообще в симе) как таковой мета-стабильности нет, так как значение триггеру присваивается за 0 время. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 21 января, 2022 Опубликовано 21 января, 2022 · Жалоба Так всё-таки это приёмник УАППа (но до чего hardware "жирный") и проблема разрешиась? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRUTOMER 0 24 января, 2022 Опубликовано 24 января, 2022 (изменено) · Жалоба Еще раз спасибо большое всем, кто помог решить проблему и написал код ревью на мой 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 "жирный") и проблема разрешиась? Просто для симуляции сделал дополнительные выходы Изменено 24 января, 2022 пользователем KRUTOMER Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 34 24 января, 2022 Опубликовано 24 января, 2022 · Жалоба 2 hours ago, KRUTOMER said: Все-таки решил чуть переписать модуль по заветам Понг П. Чу, а именно конечный автомат Модуль: Совет - лучше вставлять код в фрейм Code <>, так не слетает форматирование. А если код длинный, то заодно и в фрейм Spoiler чтобы была удобнее навигация по топикам. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться