Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

FPGA UART Receiving - how do I read and assign values

Status
Not open for further replies.

maheshkuruganti

Advanced Member level 4
Joined
May 18, 2007
Messages
106
Helped
7
Reputation
14
Reaction score
3
Trophy points
1,298
Location
India
Activity points
1,909
fpga uart

Hi,
I wrote a Generator Code and it is working.Now I want to control it using a PC by using the USB-UART Bridge.My Problem is that I have 6 32Bit Registers that I have to change the values.They are only set in One Module but how do I read and assign them all.
 

uart message gaps

The question isn't compeletely clear to me. You basically have to define a command protocol, that has a presentation for 32 Bit values (may be binary, printable hex, whatever you prefer) and a register addressing.

Assuming a binary format, that needs no decoding except for a byte mutiplexer, you have to define a unique frame start character. 9 Bit coding would provide a simple means, or 8th bit as command/start qualifier with 7-bit data.
 

Re: FPGA UART Receiving.

I am so sorry I did not post it completely. I have an FPGA Pulse Generator.It has 6 Registers of 32Bit Each. I have a deserializer to receive the Transmitted Binary No. I want to know how to assign their values from the Deserializer as its output is only 8 Bits. Thanks. The Deserializer code is given below.
Code:
 // RS-232 RX module
// (c) fpga4fun.com KNJN LLC - 2003, 2004, 2005, 2006

module async_receiver(clk, RxD, RxD_data_ready, RxD_data, RxD_endofpacket, RxD_idle);
input clk, RxD;
output RxD_data_ready;  // onc clock pulse when RxD_data is valid
output [7:0] RxD_data;

parameter ClkFrequency = 25000000; // 25MHz
parameter Baud = 115200;

// We also detect if a gap occurs in the received stream of characters
// That can be useful if multiple characters are sent in burst
//  so that multiple characters can be treated as a "packet"
output RxD_endofpacket;  // one clock pulse, when no more data is received (RxD_idle is going high)
output RxD_idle;  // no data is being received

// Baud generator (we use 8 times oversampling)
parameter Baud8 = Baud*8;
parameter Baud8GeneratorAccWidth = 16;
wire [Baud8GeneratorAccWidth:0] Baud8GeneratorInc = ((Baud8<<(Baud8GeneratorAccWidth-7))+(ClkFrequency>>8))/(ClkFrequency>>7);
reg [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc;
always @(posedge clk) Baud8GeneratorAcc <= Baud8GeneratorAcc[Baud8GeneratorAccWidth-1:0] + Baud8GeneratorInc;
wire Baud8Tick = Baud8GeneratorAcc[Baud8GeneratorAccWidth];

////////////////////////////
reg [1:0] RxD_sync_inv;
always @(posedge clk) if(Baud8Tick) RxD_sync_inv <= {RxD_sync_inv[0], ~RxD};
// we invert RxD, so that the idle becomes "0", to prevent a phantom character to be received at startup

reg [1:0] RxD_cnt_inv;
reg RxD_bit_inv;

always @(posedge clk)
if(Baud8Tick)
begin
	if( RxD_sync_inv[1] && RxD_cnt_inv!=2'b11) RxD_cnt_inv <= RxD_cnt_inv + 2'h1;
	else 
	if(~RxD_sync_inv[1] && RxD_cnt_inv!=2'b00) RxD_cnt_inv <= RxD_cnt_inv - 2'h1;

	if(RxD_cnt_inv==2'b00) RxD_bit_inv <= 1'b0;
	else
	if(RxD_cnt_inv==2'b11) RxD_bit_inv <= 1'b1;
end

reg [3:0] state;
reg [3:0] bit_spacing;

// "next_bit" controls when the data sampling occurs
// depending on how noisy the RxD is, different values might work better
// with a clean connection, values from 8 to 11 work
wire next_bit = (bit_spacing==4'd10);

always @(posedge clk)
if(state==0)
	bit_spacing <= 4'b0000;
else
if(Baud8Tick)
	bit_spacing <= {bit_spacing[2:0] + 4'b0001} | {bit_spacing[3], 3'b000};

always @(posedge clk)
if(Baud8Tick)
case(state)
	4'b0000: if(RxD_bit_inv) state <= 4'b1000;  // start bit found?
	4'b1000: if(next_bit) state <= 4'b1001;  // bit 0
	4'b1001: if(next_bit) state <= 4'b1010;  // bit 1
	4'b1010: if(next_bit) state <= 4'b1011;  // bit 2
	4'b1011: if(next_bit) state <= 4'b1100;  // bit 3
	4'b1100: if(next_bit) state <= 4'b1101;  // bit 4
	4'b1101: if(next_bit) state <= 4'b1110;  // bit 5
	4'b1110: if(next_bit) state <= 4'b1111;  // bit 6
	4'b1111: if(next_bit) state <= 4'b0001;  // bit 7
	4'b0001: if(next_bit) state <= 4'b0000;  // stop bit
	default: state <= 4'b0000;
endcase

reg [7:0] RxD_data;
always @(posedge clk)
if(Baud8Tick && next_bit && state[3]) RxD_data <= {~RxD_bit_inv, RxD_data[7:1]};

reg RxD_data_ready, RxD_data_error;
always @(posedge clk)
begin
	RxD_data_ready <= (Baud8Tick && next_bit && state==4'b0001 && ~RxD_bit_inv);  // ready only if the stop bit is received
	RxD_data_error <= (Baud8Tick && next_bit && state==4'b0001 &&  RxD_bit_inv);  // error if the stop bit is not received
end

reg [4:0] gap_count;
always @(posedge clk) if (state!=0) gap_count<=5'h00; else if(Baud8Tick & ~gap_count[4]) gap_count <= gap_count + 5'h01;
assign RxD_idle = gap_count[4];
reg RxD_endofpacket; always @(posedge clk) RxD_endofpacket <= Baud8Tick & (gap_count==5'h0F);

endmodule
 

Re: FPGA UART Receiving.

Yes, as assumed in my post. Your design misses the next higher level that decodes write commands to specific registers. But before wiring the design, the command structure must be defined.

You should think of the decoder as a simple state machine. Initially it's waiting for an unique command start. Possiby, an idle timeout of e.g. one UART frame can be used as start sync. In this case, you can use a simple binary format: one address byte and four data bytes. If the consistency of register values has to be maintained in operation, an intermediate storage register for a 32-bit word is necessary, also an address storage register and a byte counter respectively command decoder state variable. After arrival of the fourth data byte, the intermediate storage is written to the addressed register and the state is reset to idle. So continous writes are possible without waiting for the timeout countdown as well.

Simple and straightforward, to my opinion.
 

Re: FPGA UART Receiving.

I am new to Verilog and would like to know if you know of any resources that may have such a code or a tutorial on how to write State Machines.I have not used State Machines till date as all of my applications required a Parallel Approach.

Thank You
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top