66011008 WARNING - The following clock signals will be routed by using generic routing resource and may suffer from excessive delay and/or skew.
Signal=i2c_master/CLK_FSM loads=11 clock_loads=4
Thanks, but my design do not worked well and I see a lot of unexpected events in my logic.This is just a warning. If the the design is working in hardware you may ignore it.
Generally system clocks are routed using dedicated routing resources. The tools are intelligent enough to dedicate resources to such system clocks (that must reach to most parts of the design) from your RTL design.
How I fix that warning?
Is this an IP core or your own design?
I see this is an I2C clock and this clock need not reach to other parts of the design. If this is your design, then try manually inserting a global clock buffer to the I2C clock path.
Is this an IP core or your own design?
I see this is an I2C clock and this clock need not reach to other parts of the design. If this is your design, then try manually inserting a global clock buffer to the I2C clock path.
I already burn my design code to the fpga and I test it by oscilloscope and I see that everything looked good, I meant to the I2C communication between EEPROM and FPGA, but when I perform little changes in my code all the data line looks terrible and I don't find the reason why.. how testbench can help me in such a case?@KingMoshe ,
Regarding the testbench, I do not have a testbench yet.
That means you do not even know if your design does what it is supposed to do.
So it does not make any sense to do PnR of a design which is not functionally verified.
Then I repeat again....
First things first. Did your perform thorough functional verification of your design via simulation?
i.e. do you have a testbench that exercises your design quite well?
If not it must be done asap without even thing about other design steps.
Hi,
just a guess:
You generated the I2C clock by clock dividers / counters, instead of generating clock_enable signals.
I assume the problem lies in your code. Thus I recommend to show your code.
Klaus
module I2C_MASTER(
clk,
RST,
// I2C_SDA,
I2C_SCL,
data,
data_addr,
read_en,
start,
// ready,
WC,
I2C_SDA_OUT,
nBytes,
saved_data_read,
RAM_WR_CLK_EN,
RAM_RD_CLK_EN,
ram_addr
);
//INPUTS-----------------------------------------------------------------------------------------------------
input wire clk;
input wire RST;
input wire [7:0] data;
input wire [7:0] data_addr;
input wire read_en;
input wire start;
inout wire I2C_SDA_OUT;
input wire [7:0] nBytes;
//OUTPUTS----------------------------------------------------------------------------------------------------
reg I2C_SDA = 1;
output wire I2C_SCL;
// output wire ready;
output reg WC;
output reg [7:0] saved_data_read;
output reg RAM_WR_CLK_EN = 0;
output reg RAM_RD_CLK_EN = 0;
//LOCAL------------------------------------------------------------------------------------------------------
reg [7:0] index;
reg [7:0] state;
reg stop;
reg [7:0] count;
reg [5:0] counter = 0 ;
reg I2C_CLK = 1;
reg CLK_FSM;
reg SDAin = 0 ;
reg SDAin_en = 0;
reg i2c_scl_enable = 0;
parameter [6:0] start_init = 7'b1010011;
parameter [2:0] addr_init = 3'b001;
reg [7:0] saved_data; //saved DATA for write to eeprom
reg [7:0] saved_data_addr; //saved ADDRESS BYTR
reg [7:0] data_read; //data read from eeprom
reg [7:0] nBytes_count;
reg [7:0] total_params;
output reg [7:0] ram_addr; //Ram address to write the data from eeprom
localparam STATE_IDLE = 0;
localparam STATE_START = 1;
localparam STATE_INIT_START = 2;
localparam STATE_INIT_ADDR = 3;
localparam STATE_ADDR = 4;
localparam STATE_RW_RD = 5;
localparam STATE_WACK = 6;
localparam STATE_DATA_ADDR = 7;
localparam STATE_WACK2 = 8;
localparam STATE_DATA_WRITE = 9;
localparam STATE_DATA_READ = 10;
localparam STATE_WACK3_WRITE = 11;
localparam STATE_NO_ACK = 12;
localparam STATE_STOP_LOW = 13;
localparam STATE_STOP_HIGH = 14;
localparam STATE_WACK_READ = 15;
localparam STATE_RD_EN = 16;
localparam STATE_START_READ = 17;
localparam STATE_READ_START_LOW = 18;
localparam STATE_READ_START_HIGH = 19;
localparam STATE_INIT_START2 = 20;
localparam STATE_INIT_ADDR2 = 21;
assign I2C_SCL = (i2c_scl_enable == 0) ? 1'b1 : I2C_CLK;
// assign ready = ((RST == 0) &&(state == STATE_IDLE)) ? 1 : 0;
// assign I2C_SDA_OUT = I2C_SDA ; // SDA is defined as 'HIGH Z' or '0'.
assign I2C_SDA_OUT = ( I2C_SDA ) ? 1'bZ : 1'b0 ; // SDA is defined as 'HIGH Z' or '0'.
// --------------------------------------
// ------------CLKS GENERATOR------------
// --------------------------------------
// 26.6MHz -> 350kHz
always @(negedge clk) // Generating clocks for SCL and FSM.
begin // The FSM clock should be delayed in order to ensure that
SDAin <= I2C_SDA_OUT; // SDA bits change only when SCL is LOW, and data acquisition
if ( counter == 0 ) I2C_CLK <= ~I2C_CLK; // happans only when SCL is high.
if ( counter == 38 ) counter <= 0 ;
else counter <= counter + 1'b1; // 26.6MHz / (38 * 2) = 350kHz (1.42usec on-time)
if ( counter == 19) CLK_FSM <= ~CLK_FSM; // 19 / 26.6MHz = 0.714usec delay
end
always @ (negedge CLK_FSM) begin
if (RST) begin
i2c_scl_enable <= 0;
data_read <= 0;
end else begin
if (( state == STATE_IDLE) || (state == STATE_START) || (state == STATE_STOP_HIGH) || (state ==STATE_READ_START_LOW)) begin
i2c_scl_enable <= 0;
end
else begin
i2c_scl_enable <= 1;
end
if (SDAin_en == 1) // SDA input is sampled on the negedge of CLK_FSM,
begin // when CLK_SCL should be steady HIGH.
data_read[index] <= SDAin;
end
end
end
always @ (posedge CLK_FSM)
begin
if (RST || start == 0)
begin
state <= 0; //state = IDLE
I2C_SDA <= 1;
count <= 8'd0;
//start_init <= 4'b1010;
//addr_init <= 3'b011;
stop <= 0;
WC <= 1'b1;
saved_data_addr <= 0; // ADDRESS BYTE
saved_data <= 0; // SAVED DATA TO WRITE TO EEPROM
nBytes_count <= nBytes; // BYTES NUMBER TO READ
RAM_WR_CLK_EN <= 0;
RAM_RD_CLK_EN <= 1;
total_params <= 0;
saved_data_read <= 0; //SAVED DATA FROM EEPROM TO RAM
end
else begin
case (state)
STATE_IDLE: begin //WAITING TO START COMMAND
I2C_SDA <= 1;
if (start && (stop == 0)) begin
state <= STATE_START;
saved_data <= data;
saved_data_addr <= data_addr;
nBytes_count <= nBytes;
total_params <= nBytes;
end
else state <= STATE_IDLE;
end
STATE_START: begin //SDA TO "0" WHEN SCL IS "1"
I2C_SDA <= 0;
state <= STATE_INIT_START;
count <= 6;
RAM_RD_CLK_EN <= 0;
end
STATE_INIT_START: begin //GENERATING SDA: 1010
I2C_SDA <= start_init[count];
if (count == 0) begin
state <= STATE_RW_RD;
//count <= 2;
end
else count <= count - 1'b1;
end
/*
STATE_INIT_ADDR: begin //GENERATING SDA TO SALVE EEPROM ADDR: 011
I2C_SDA <= addr_init[count];
if (count == 0) state <= STATE_RW_RD;
else count <= count - 1'b1;
end
*/
STATE_RW_RD: begin //"0": WRITE, Selective READ and Sequential READ, "1": Imidiate READ
I2C_SDA <= 0;
state <= STATE_WACK;
end
STATE_WACK: begin //WAINTING FOR ACK
if(read_en == 0) begin
WC <= 1'b0;
state <= STATE_DATA_ADDR; end
else begin
WC <= 1'b1;
state <= STATE_DATA_ADDR; end
count <= 7;
end
STATE_DATA_ADDR: begin //EEPROM ADDRESSS POINTER
I2C_SDA <= saved_data_addr[count];
if (count == 0) state <= STATE_WACK2;
else count <= count - 1'b1;
end
STATE_WACK2: begin //WAITING FOR ACK
if(read_en == 0) state <= STATE_DATA_WRITE;
else state <= STATE_READ_START_HIGH;
count <= 7;
end
//WRITE
STATE_DATA_WRITE: begin
I2C_SDA <= saved_data[count]; //DATA WRITE
if (count == 0) state <= STATE_WACK3_WRITE;
else count <= count - 1'b1;
end
STATE_WACK3_WRITE: begin //WAITING FOR ACK
state <= STATE_STOP_LOW;
end
//READ
STATE_READ_START_HIGH: // Start Condition - SDA to HIGH.
begin // (SCL also gets HIGH for this state).
I2C_SDA <= 1;
state <= STATE_READ_START_LOW;
// RAM_WR_CLK_EN <= 1;
end
STATE_READ_START_LOW: // Start Condition - SDA to LOW when SCL is HIGH.
begin
I2C_SDA <= 0;
state <= STATE_INIT_START2;
count <= 6;
end
STATE_INIT_START2: begin //GENERATING SDA: 1010 011
I2C_SDA <= start_init[count];
if (count == 0) begin
state <= STATE_RD_EN;
// count <= 2;
end
else count <= count - 1'b1;
end
/*
STATE_INIT_ADDR2: begin //GENERATING SDA TO EEPROM ADDR: 011
I2C_SDA <= addr_init[count];
if (count == 0) state <= STATE_RD_EN;
else count <= count - 1'b1;
end
*/
STATE_RD_EN: begin //"0" WRITE, "1" READ
I2C_SDA <= 1;
state <= STATE_WACK_READ;
end
STATE_WACK_READ: begin //WAITING FOR ACK
state <= STATE_DATA_READ;
index <= 7;
end
STATE_DATA_READ: begin //RECIVE READ
I2C_SDA <= 1;
SDAin_en <= 1;
if ( index == 0 )
begin
index <= 7;
state <= STATE_NO_ACK;
end
else index <= index - 1'b1;
end
STATE_NO_ACK: begin //WAITING FOR NO ACK // if there are any bytes left to be read - going back
SDAin_en <= 0; // to previous state.
saved_data_read <= data_read;
ram_addr = total_params - nBytes_count;
if ( nBytes_count == 0 )
begin
I2C_SDA <= 1; // MASTER NO ACK FOR STOP READING
state <= STATE_STOP_LOW;
end
else
begin
I2C_SDA <= 0;
index <= 7;
nBytes_count <= nBytes_count - 1'b1;
state <= STATE_DATA_READ;
end
end
//STOP
STATE_STOP_LOW: begin //STOP CONDITION
I2C_SDA <= 0;
state <= STATE_STOP_HIGH;
end
STATE_STOP_HIGH: begin //STOP CONDITION
I2C_SDA <= 1;
state <= STATE_IDLE;
stop <= 1;
WC <= 1;
RAM_WR_CLK_EN <= 0;
end
endcase
end
end
endmodule
I´m no expert.if ( counter == 19) CLK_FSM <= ~CLK_FSM;
But here you treat it as a clock.always @ (posedge CLK_FSM)
Can you please detail more? I am not sure I understand what I should do.Hi,
I´m no expert.
But as far as I understand: here you generate a standard signal (not a dedicated clock)
But here you treat it as a clock.
****
I´d rather set flags: rising_edge_flag and falling_edge_flag within the "always @(negedge clk) "
..and process and clear them in the according sections.
***
In either case (above solution and your solution) it is processed one master_clock delayed
If you don´t want the delay you have to process it within the "always @(negedge clk) " section.
Klaus
How I generate clock enable signal?The correct way to handle the problem is to switch from generated clocks to a common design clock with clock enables. This eleminates clock related warnings and many possible timing issues.
I think it´s the most often discussed topic regarding FPGAs. Thus there already are very many examples around. Just do a search.How I generate clock enable signal?
Do you have an example ?
Thanks
Sorry, but I don't find an example and it will be great if you have a tutorial because I am losing a lot of time.Hi,
I think it´s the most often discussed topic regarding FPGAs. Thus there already are very many examples around. Just do a search.
Basically what I described in post#12 with the flags is very similar.
Klaus
if ( counter == 38 ) counter <= 0 ;
else counter <= counter + 1'b1; // 26.6MHz / (38 * 2) = 350kHz (1.42usec on-time)
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?