Estoy tratando de generar un código Verilog para el transmisor que envía datos en 1 bit de inicio y 1 bit de parada desde FPGA y recibo en mi PC con 1 bit de parada. Si alguien puede proporcionar un enlace o sugerencia, será muy apreciado.
El código es el siguiente:
module tb_tx_serial (input clk, output TxD);
// Inputs
reg TxD_start=0;
reg [7:0] TxD_data=0;
reg [7:0] count=0;
// Outputs
//wire TxD;
wire TxD_busy;
// Instantiate the Unit Under Test (UUT)
async_transmitter uut (
.clk(clk),
.TxD_start(TxD_start),
.TxD_data(TxD_data),
.TxD(TxD),
.TxD_busy(TxD_busy)
);
always @(posedge clk) begin
//if(count <= 6) begin
TxD_start <= 1'b1;
TxD_data <= count;
// else TxD_data <= 8'b10111011;
end
always @(posedge clk) begin
count <= count + 1;
end
endmodule
module async_transmitter (
input clk,
input TxD_start,
input [7:0] TxD_data,
output TxD,
output TxD_busy
);
// Assert TxD_start for (at least) one clock cycle to start transmission of TxD_data
// TxD_data is latched so that it doesn't have to stay valid while it is being sent
parameter ClkFrequency = 50000000; // 50MHz
parameter Baud = 9600;
//generate
// if(ClkFrequency<Baud*8 && (ClkFrequency % Baud!=0)) ASSERTION_ERROR PARAMETER_OUT_OF_RANGE("Frequency incompatible with requested Baud rate");
//endgenerate
////////////////////////////////
'ifdef SIMULATION
wire BitTick = 1'b1; // output one bit per clock cycle
'else
wire BitTick;
BaudTickGen #(ClkFrequency, Baud) tickgen (
.clk(clk),
.enable(TxD_busy),
.tick(BitTick)
);
'endif
reg [3:0] TxD_state = 0;
wire TxD_ready = (TxD_state==0);
assign TxD_busy = ~TxD_ready;
reg [7:0] TxD_shift = 0;
always @(posedge clk) begin
if (TxD_ready & TxD_start)
TxD_shift <= TxD_data;
else if (TxD_state[3] & BitTick)
TxD_shift <= (TxD_shift >> 1);
case(TxD_state)
4'b0000: if (TxD_start) TxD_state <= 4'b0100;
4'b0100: if (BitTick) TxD_state <= 4'b1000; // start bit
4'b1000: if (BitTick) TxD_state <= 4'b1001; // bit 0
4'b1001: if (BitTick) TxD_state <= 4'b1010; // bit 1
4'b1010: if (BitTick) TxD_state <= 4'b1011; // bit 2
4'b1011: if (BitTick) TxD_state <= 4'b1100; // bit 3
4'b1100: if (BitTick) TxD_state <= 4'b1101; // bit 4
4'b1101: if (BitTick) TxD_state <= 4'b1110; // bit 5
4'b1110: if (BitTick) TxD_state <= 4'b1111; // bit 6
4'b1111: if (BitTick) TxD_state <= 4'b0010; // bit 7
4'b0010: if (BitTick) TxD_state <= 4'b0011; // stop1
4'b0011: if (BitTick) TxD_state <= 4'b0000; // stop2
default: if (BitTick) TxD_state <= 4'b0000;
endcase
end
assign TxD = (TxD_state<4) | (TxD_state[3] & TxD_shift[0]); // put together the start, data and stop bits
endmodule
////////////////////////////////////////////////////////
// dummy module used to be able to raise an assertion in Verilog
//module ASSERTION_ERROR();
//endmodule
'timescale 1ns / 1ps
////////////////////////////////////////////////////////
module BaudTickGen
(
input clk, enable,
output tick // generate a tick at the specified baud rate * oversampling
);
parameter ClkFrequency = 50000000;
parameter Baud = 9600;
parameter Oversampling = 1;
function integer log2(input integer v);
begin
log2=0;
while (v>>log2) log2 = log2 + 1;
end
endfunction
localparam AccWidth = log2(ClkFrequency/Baud)+8; // +/- 2% max timing error over a byte
reg [AccWidth:0] Acc = 0;
localparam ShiftLimiter = log2(Baud*Oversampling >> (31-AccWidth)); // this makes sure Inc calculation doesn't overflow
localparam Inc = ((Baud*Oversampling << (AccWidth-ShiftLimiter))+(ClkFrequency>>(ShiftLimiter+1)))/(ClkFrequency>>ShiftLimiter);
always @(posedge clk) begin
if (enable)
Acc <= Acc[AccWidth-1:0] + Inc[AccWidth:0];
else Acc <= Inc[AccWidth:0];
end
assign tick = Acc[AccWidth];
endmodule
Banco de pruebas:
'timescale 1ns / 1ps
module test_srltst;
// Inputs
reg clk;
// Outputs
wire TxD;
// Instantiate the Unit Under Test (UUT)
tb_tx_serial uut (
.clk(clk),
.TxD(TxD)
);
initial
begin
clk = 0;
forever #10 clk = ~clk;
end
endmodule
No sé si ayudaría o no, pero he proporcionado esto en mi archivo UCF para UART
#NET "TxD" LOC = "M14" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = SLOW ;