Jump to content

    

KRUTOMER

Участник
  • Posts

    5
  • Joined

  • Last visited

Everything posted by KRUTOMER


  1. Еще раз спасибо большое всем, кто помог решить проблему и написал код ревью на мой 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 Просто для симуляции сделал дополнительные выходы
  2. Да, и вправду по невнимательности не добавил DATA_serial и инстанс. Сбасибо большое
  3. Вот код самого тестбенча: `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 schematic.pdf
  4. Описываю поведение простого UART-передатчика на Verilog в среде Xiling Vivado 2018.2. При присваивании D-триггеру значения с входного порта, он переходит в Z-состояние. Также при попытке присвоить этот сигнал цепи через оператор непрерывного присваивания assign, цепь также принимает высокоимпедансное состояние. В чем может быть причина такого поведения/симуляции, и как это можно исправить? Описание модуля следующее: