Sunday, 21 January 2018

Arduino FPGA interface using Verilog RS232 serial communication xilinx spartan 3 Waveshare






SERVO CONTROL MODULE
module RCServo(clk50, RxD, RCServo_pulse);
input clk50, RxD;
output RCServo_pulse;

////////////////////////////////////////////////////////////////////////////
// use the serial port to control the servo
wire clk;
wire RxD_data_ready;
wire [7:0] RxD_data;
async_receiver deserialer(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data));  

reg [7:0] RxD_data_reg;
always @(posedge clk) if(RxD_data_ready) RxD_data_reg <= RxD_data;

////////////////////////////////////////////////////////////////////////////
reg [23:0]count;


//Clock division 50Mhz input => output 25Mhz
always @(posedge clk50) begin
count <= count+1;
end
assign clk = count[0];
// divide the clock

parameter ClkDiv = 98;  // 25000000/1000/256 = 97.56

reg [6:0] ClkCount;
reg ClkTick;
always @(posedge clk) ClkTick <= (ClkCount==ClkDiv-2);
always @(posedge clk) if(ClkTick) ClkCount <= 0; else ClkCount <= ClkCount + 1;

////////////////////////////////////////////////////////////////////////////
reg [11:0] PulseCount;
always @(posedge clk) if(ClkTick) PulseCount <= PulseCount + 1;

// make sure the RCServo_position is stable while the pulse is generated
reg [7:0] RCServo_position;
always @(posedge clk) if(PulseCount==0) RCServo_position <= RxD_data_reg;

reg RCServo_pulse;
always @(posedge clk) RCServo_pulse <= (PulseCount < {4'b0001, RCServo_position});

endmodule


SERIAL COMMUNICATION MODULE
<4 -="" .enable="" .tick="" 16="" 1="" 25mhz="" 2="" 8="" a="" also="" always="" amp="" and="" are="" as="" asserted="" assertion_error="" async_receiver="" at="" aud="" b00="" b0="" b11="" b1="" baud="" baudtickgen="" be="" been="" begin="" bit="" bits="" burst="" by="" can="" capture="" characters="" clk="" clkfrequency="25000000;" clock="" current="" cycle="" d1="" data="" decide="" default="" detect="" detected="" domain="" each="" else="" end="" endgenerate="" endmodule="" filter="" filter_cnt="" fixed="" for="" function="" gap="" generate="" going="" good="" has="" high="" higher="" i.e.="" if="" ifdef="" ilter_cnt="=2" in="" input="" integer="" is="" it="" line="" lkfrequency="" log2="0;" low="" module="" multiple="" needs="" no="" nvalid="" occurs="" of="" one="" only="" our="" output="" oversample="" oversampling="" oversamplingtick="" packet="" parameter="" parameter_out_of_range="" per="" posedge="" power="" put="" quality="" rate="" receive="" received="" reception="" reg="" requency="" right="" rxd="" rxd_bit="" rxd_data="0," rxd_data_ready="" rxd_endofpacket="0" rxd_idle="" rxd_state="0;" rxd_sync="" sample="" samplenow="1" sent="" simulation="" so="" start="" stop="" stream="" synchronize="" that="" the="" tickgen="" time="" times="" to="" together="" too="" treated="" txd_shift="" use="" useful="" v="" valid="" value="" versampling-1="" versampling="" versamplingtick="" we="" when="" while="" wire="" xd_state="" xd_sync=""><4 -="" .enable="" .tick="" 16="" 1="" 25mhz="" 2="" 8="" a="" also="" always="" amp="" and="" are="" as="" asserted="" assertion_error="" async_receiver="" at="" aud="" b00="" b0="" b11="" b1="" baud="" baudtickgen="" be="" been="" begin="" bit="" bits="" burst="" by="" can="" capture="" characters="" clk="" clkfrequency="25000000;" clock="" current="" cycle="" d1="" data="" decide="" default="" detect="" detected="" domain="" each="" else="" end="" endgenerate="" endmodule="" filter="" filter_cnt="" fixed="" for="" function="" gap="" generate="" going="" good="" has="" high="" higher="" i.e.="" if="" ifdef="" ilter_cnt="=2" in="" input="" integer="" is="" it="" line="" lkfrequency="" log2="0;" low="" module="" multiple="" needs="" no="" nvalid="" occurs="" of="" one="" only="" our="" output="" oversample="" oversampling="" oversamplingtick="" packet="" parameter="" parameter_out_of_range="" per="" posedge="" power="" put="" quality="" rate="" receive="" received="" reception="" reg="" requency="" right="" rxd="" rxd_bit="" rxd_data="0," rxd_data_ready="" rxd_endofpacket="0" rxd_idle="" rxd_state="0;" rxd_sync="" sample="" samplenow="1" sent="" simulation="" so="" start="" stop="" stream="" synchronize="" that="" the="" tickgen="" time="" times="" to="" together="" too="" treated="" txd_shift="" use="" useful="" v="" valid="" value="" versampling-1="" versampling="" versamplingtick="" we="" when="" while="" wire="" xd_state="" xd_sync="">
// RS-232 RX and TX module


// The RS-232 settings are fixed
// TX: 8-bit data, 2 stop, no-parity
// RX: 8-bit data, 1 stop, no-parity (the receiver can accept more stop bits of course)

//`define SIMULATION   // in this mode, TX outputs one bit per clock cycle
                       // and RX receives one bit per clock cycle (for fast simulations)

////////////////////////////////////////////////////////
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 = 25000000;	// 25MHz
parameter Baud = 115200;

generate
	if(ClkFrequency> 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 -="" .enable="" .tick="" 16="" 1="" 25mhz="" 2="" 8="" a="" also="" always="" amp="" and="" are="" as="" asserted="" assertion_error="" async_receiver="" at="" aud="" b00="" b0="" b11="" b1="" baud="" baudtickgen="" be="" been="" begin="" bit="" bits="" burst="" by="" can="" capture="" characters="" clk="" clkfrequency="25000000;" clock="" current="" cycle="" d1="" data="" decide="" default="" detect="" detected="" domain="" each="" else="" end="" endgenerate="" endmodule="" filter="" filter_cnt="" fixed="" for="" function="" gap="" generate="" going="" good="" has="" high="" higher="" i.e.="" if="" ifdef="" ilter_cnt="=2" in="" input="" integer="" is="" it="" line="" lkfrequency="" log2="0;" low="" module="" multiple="" needs="" no="" nvalid="" occurs="" of="" one="" only="" our="" output="" oversample="" oversampling="" oversamplingtick="" packet="" parameter="" parameter_out_of_range="" per="" posedge="" power="" put="" quality="" rate="" receive="" received="" reception="" reg="" requency="" right="" rxd="" rxd_bit="" rxd_data="0," rxd_data_ready="" rxd_endofpacket="0" rxd_idle="" rxd_state="0;" rxd_sync="" sample="" samplenow="1" sent="" simulation="" so="" start="" stop="" stream="" synchronize="" that="" the="" tickgen="" time="" times="" to="" together="" too="" treated="" txd_shift="" use="" useful="" v="" valid="" value="" versampling-1="" versampling="" versamplingtick="" we="" when="" while="" wire="" xd_state="" xd_sync="">>log2) log2=log2+1; end endfunction
localparam l2o = log2(Oversampling);
reg [l2o-2:0] OversamplingCnt = 0;
always @(posedge clk) if(OversamplingTick) OversamplingCnt <= (RxD_state==0) ? 1'd0 : OversamplingCnt + 1'd1;
wire sampleNow = OversamplingTick && (OversamplingCnt==Oversampling/2-1);
`endif

// now we can accumulate the RxD bits in a shift-register
always @(posedge clk)
case(RxD_state)
	4'b0000: if(~RxD_bit) RxD_state <= `ifdef SIMULATION 4'b1000 `else 4'b0001 `endif;  // start bit found?
	4'b0001: if(sampleNow) RxD_state <= 4'b1000;  // sync start bit to sampleNow
	4'b1000: if(sampleNow) RxD_state <= 4'b1001;  // bit 0
	4'b1001: if(sampleNow) RxD_state <= 4'b1010;  // bit 1
	4'b1010: if(sampleNow) RxD_state <= 4'b1011;  // bit 2
	4'b1011: if(sampleNow) RxD_state <= 4'b1100;  // bit 3
	4'b1100: if(sampleNow) RxD_state <= 4'b1101;  // bit 4
	4'b1101: if(sampleNow) RxD_state <= 4'b1110;  // bit 5
	4'b1110: if(sampleNow) RxD_state <= 4'b1111;  // bit 6
	4'b1111: if(sampleNow) RxD_state <= 4'b0010;  // bit 7
	4'b0010: if(sampleNow) RxD_state <= 4'b0000;  // stop bit
	default: RxD_state <= 4'b0000;
endcase

always @(posedge clk)
if(sampleNow && RxD_state[3]) RxD_data <= {RxD_bit, RxD_data[7:1]};

//reg RxD_data_error = 0;
always @(posedge clk)
begin
	RxD_data_ready <= (sampleNow && RxD_state==4'b0010 && RxD_bit);  // make sure a stop bit is received
	//RxD_data_error <= (sampleNow && RxD_state==4'b0010 && ~RxD_bit);  // error if a stop bit is not received
end

`ifdef SIMULATION
assign RxD_idle = 0;
`else
reg [l2o+1:0] GapCnt = 0;
always @(posedge clk) if (RxD_state!=0) GapCnt<=0; else if(OversamplingTick & ~GapCnt[log2(Oversampling)+1]) GapCnt <= GapCnt + 1'h1;
assign RxD_idle = GapCnt[l2o+1];
always @(posedge clk) RxD_endofpacket <= OversamplingTick & ~GapCnt[l2o+1] & &GapCnt[l2o:0];
`endif

endmodule


////////////////////////////////////////////////////////
// dummy module used to be able to raise an assertion in Verilog
module ASSERTION_ERROR();
endmodule


////////////////////////////////////////////////////////
module BaudTickGen(
	input clk, enable,
	output tick  // generate a tick at the specified baud rate * oversampling
);
parameter ClkFrequency = 25000000;
parameter Baud = 115200;
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) if(enable) Acc <= Acc[AccWidth-1:0] + Inc[AccWidth:0]; else Acc <= Inc[AccWidth:0];
assign tick = Acc[AccWidth];
endmodule


////////////////////////////////////////////////////////



////////////////////////////////////////////////////////




CONSTRAINTS
#Created by Constraints Editor (xc3s250e-tq144-4) - 2017/07/29
NET "clk50" LOC = "P129"; #TNM_NET = clk;
TIMESPEC TS_clk = PERIOD "clk" 50 MHz HIGH 50%;

#16I/Os_1 (output)
NET "RxD"  LOC = "p94"  ;
NET "RCServo_pulse"  LOC = "p85"  ;






ARDUINO

void setup() {

  Serial.begin(115200); // opens serial port, sets data rate to 9600 bps

}

void loop() {
  byte i=0;
  byte j=255;
  Serial.println(i);
  delay(5000);
  Serial.println(j);
  delay(5000);
  
  
}

3 comments:

  1. in serial communication module
    <4------------------> first line show syntax error , Please help

    ReplyDelete
    Replies
    1. https://t.me/fpga_es

      In this group there are some collaborators who could guide me.


      Delete
  2. in serial communication module
    <4------------------> first line show syntax error , Please help

    ReplyDelete