Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic 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.

Register Log in

help : error in my code (vhdl code for i2c master simulate on xilinx spartan3)

Status
Not open for further replies.

gholamzadeh

Newbie level 4
Joined
Jun 7, 2011
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,414
hi....my vhdl code for i2c master have error in synthesis in xilinx....error is about clk and sclk....but modelsim don't show any error! what's wrong about my code?
thank u 4 help..
my code:
(vhdl code for i2c master simulate on xilinx spartan3)

--------------------------------
Library IEEE;
Use IEEE.std_logic_1164.all;
Use IEEE.std_logic_arith.all;
use work.basic_utility.all;
entity i2c_master is
port(addr:in qit_vector(7 downto 0);
enablemaster:in bit;
num: integer;
reset:in std_logic;
clk: in std_logic;
sda : inout qit;
sclk : inout qit
);
end i2c_master;

Architecture Gate_level Of i2c_master is

type state is(idle,start,start_2,start_3,start_4,start_5,adr_ersal,adr_ersal2,wait_ack,ersal,m_read,m_write,write2,stop,stop_2,stop_3,stop_4,read2,wait_start_bit,rcv_addr,rcv2_adr,check_addr,send_ack,m_send_ack,read_write, write,read,
rcv_data,wait_stop_bit,wait_stop_bit2,send_data,wait_ack_sl);

type state2 is(st1,st2,idle);
signal rd1_wr2,j,t,bytenum:integer;
signal adcnt,datcnt:integer;
signal shiftreg_adr:qit_vector(7 downto 0);

signal time_out_cnt:integer;
signal m_state : state:= idle;
signal m2_state: state2 := idle;

constant mem2:qit_vector(7 downto 0):="10001011";
signal a:bit;

--------------------------------------------------------------------

signal mem1_from_slv:qit_vector(7 downto 0);
signal mem2_from_slv:qit_vector(7 downto 0);

--------------------------------------------------------------------
signal sl_shiftreg_adr:qit_vector(7 downto 0);
type byte is array (7 downto 0) of qit;
signal sl_shiftreg_dat:byte;
signal shiftreg_dat:byte;
constant mem1:byte:="10111111";
signal ssclk,dsclk:qit;
signal ssda,dsda:qit;
signal m,n,w:std_logic;
signal sl_datcnt, sl_adrcnt,clkcnt,clkcnt2:integer;
constant m1:byte:="10101010";
constant m2:qit_vector(7 downto 0):="11101101";
----------------------------------------------------------------

type mem is array (1 to 100) of byte;
signal mem_out:mem;

--signal mem_out2:qit_vector(7 downto 0);

begin

process(clk,sclk,reset)
variable y_bit:qit;
variable x_bit:qit;

begin
if reset='1' then

sclk<='1';
sda<='1';
shiftreg_adr<=(others=>'0');
shiftreg_dat<=(others=>'0');
m_state <= idle;
m2_state <= idle;
rd1_wr2 <= 0;
bytenum<=1;

sl_shiftreg_adr<=(others=>'0');
sl_shiftreg_dat<=(others=>'0');
m_state <= idle;
end if;
-----------------------------
case m_state is
when idle => if (clk'event and clk='1') then
shiftreg_adr<=(others=>'0');
shiftreg_dat<=(others=>'0');
bytenum<=1;
sclk<='1';
sda<='1';
if enablemaster='0' then sda<='z'; sclk<='z'; m_state<= wait_start_bit;
else m_state<= start;
end if;
end if;

-------------
when start => if (clk'event and clk='1') then

sclk <= '1';
sda <= '1';
m_state <= start_2;
end if;
when start_2 => if (clk'event and clk='1') then

sclk <= '1';
sda <= '1';

m_state <= start_3;
end if;
when start_3 => if (clk'event and clk='1') then

sclk <= '1';
sda <= '0';
m_state <= start_4;
end if;
when start_4 => if (clk'event and clk='1') then

sclk <= '1';
sda <= '0';
m_state <= start_5;
end if;
when start_5 => if (clk'event and clk='1') then

sclk<= '1';
sda <= '0';
m_state <= adr_ersal;
end if;
------------------------------------------- ferestadane start bit
when adr_ersal => if (clk'event and clk='1') then

m_state <= adr_ersal2;
adcnt <=8;
shiftreg_adr <= addr;
sclk <= '1';
m2_state <= st2;
if addr(0)='0' then
rd1_wr2 <=2;
elsif addr(0)='1' then
rd1_wr2 <=1; end if;

end if;

when adr_ersal2 => if (sclk'event and sclk='0') then
x_bit:= shiftreg_adr(7);
for i in 7 downto 1 loop
shiftreg_adr(i) <= shiftreg_adr(i-1);
end loop;
shiftreg_adr(0) <= '0';
adcnt <= adcnt - 1;

if adcnt = 0 then
sda <= '1';
sclk <='1';
m_state <= wait_ack;
m2_state<= idle;
time_out_cnt<=5;
sda<='z';
m2_state<=st2;
sclk<='0';
else
sda <= x_bit;
m_state <= adr_ersal2;
end if;
end if;

------------------------------------------------ersale addresse slave dar sdata
when wait_ack =>
if sclk'event and sclk='1' then
if sda='0' then m_state <= ersal;
m2_state<=idle;

elsif time_out_cnt=0 then m_state <= idle;
m2_state<=idle;
else
m_state<= wait_ack;
time_out_cnt<= time_out_cnt-1;
end if;
end if;
------------------------------------------------ montazere residane ack az slave mishavad
when ersal =>
-- if (clk'event and clk='1') then
if rd1_wr2=1 then
m_state <= m_read;
sda<='z';
t<=1;
elsif rd1_wr2=2 then
m_state <= m_write;
shiftreg_dat <= mem1;
if bytenum=num then
m_state <= stop;
sda<='0';
sclk<='0';
m2_state<= idle;
--if bytenum=2 then
--shiftreg_dat <= mem2;
-- elsif bytenum=1 then

-- end if;
end if;
end if;
------------------------------------------------ tashkhise read o write boodane amal
when m_write =>
-- if (clk'event and clk='1') then
datcnt <= 8;

m2_state <= st2;
m_state <= write2;
--end if;

when write2 =>

if(sclk'event and sclk='0') then
if(datcnt=0) then
sda<='z';
--***************taghyir
if bytenum=num then
m_state <= stop;
sda<='0';
sclk<='0';
m2_state<= idle;
elsif bytenum<=num then m_state<=wait_ack;
bytenum<=bytenum+1;
end if;
elsif (datcnt>0) then

datcnt<= datcnt - 1;
y_bit :=shiftreg_dat(7);

for i in 7 downto 1 loop
shiftreg_dat(i)<= shiftreg_dat(i-1);
end loop;
shiftreg_dat(0) <= '0';
sda<= y_bit;
m_state <= write2;
end if;
end if;

-----------------------------------------------------ersale dade rooye sdata zamani ke write faal bashad
when stop => if (clk'event and clk='1') then
sclk<= '0';
sda <= '0';
m_state <= stop_2;
end if;
when stop_2 => if (clk'event and clk='1') then

sclk <= '1';
sda <= '0';
m_state <= stop_3;
end if;
when stop_3 => if (clk'event and clk='1') then

sclk <= '1';
sda <= '1';

m_state <= stop_4;
end if;
when stop_4 => if (clk'event and clk='1') then


sclk <= '1';
sda <= '1';
m_state <= idle;
end if;
----------------------------------------------------ersale stop bit be slave be onvane khateme
when m_read =>
-- if (clk'event and clk='1') then
shiftreg_dat <= (others => '0');
datcnt <=8;
m_state <= read2;
m2_state<=st1;

--end if;


when read2 => if datcnt=0 then
mem_out(t) <= shiftreg_dat;
t<=t+1;
--------*********
if bytenum= num then
m_state<=stop;
m2_state <= idle;
--mem_out(num) <=shiftreg_dat;
elsif bytenum<=num then m_state<= m_send_ack;
-- mem1_from_slv <=shiftreg_dat;
bytenum<=bytenum+1;
end if;
elsif(sclk'event and sclk='1') then
for i in 7 downto 1 loop
shiftreg_dat(i)<= shiftreg_dat(i-1);
end loop;
shiftreg_dat(0)<=sda;
datcnt <= datcnt - 1;
m_state<= read2;
end if;
---------------------------


------------------------------------------------------khandane 16 bit az rooye s
when m_send_ack =>
sda <= '0';
if (sclk'event and sclk='1') then
sda <= '0';
m_state<=m_read;
sda<='z';
end if;
-----()()()()()()()()()()()()()()()()()()()()()()master

----/\/\/\/\/\\/\/\\/\\/\\/\\/\\/\\/\/\/\\/\/\/\/\\/\\/\/\\/\/\/\\\/

----()()()()()()()()()()()()()()()()()()()()()()slave

when wait_start_bit => if (clk'event and clk='1') then
ssclk <= sclk;
ssda <= sda;
dsclk <= ssclk;
dsda <= ssda;
if ssda='0' and dsda='1' then
if ssclk='1' then
m_state <= rcv_addr;
else
m_state <= wait_start_bit;
end if;
end if;
end if;
-- ---------------------------------------- ta zamani ke start bit nayayad idle mimanad
when rcv_addr => if (sclk'event and sclk='1') then
sl_shiftreg_adr<=(others =>'0');
sl_adrcnt <=8;
m_state <= rcv2_adr;
end if;

when rcv2_adr => if sl_adrcnt= 0 then m_state <= check_addr;
elsif (sclk'event and sclk='1') and ( sl_adrcnt>0 ) then
m_state <= rcv2_adr;
sl_shiftreg_adr(0) <=sda;
for i in 7 downto 1 loop

sl_shiftreg_adr(i) <= sl_shiftreg_adr(i - 1);
end loop;
sl_adrcnt <= sl_adrcnt - 1;



end if;
----------------------------------------------daryafte address az khate sdata
when check_addr =>
if "0000001"= sl_shiftreg_adr(7 downto 1) then m_state <=send_ack; j<=1;
elsif "00000000"= sl_shiftreg_adr(7 downto 0) then m_state <=send_ack; j<=1;
else
m_state <= wait_stop_bit2;
sda <='z';
end if;

----------------------------------------------addresse daryafti ra ba addrese khodash moghayese mikonad
when send_ack =>
sda <= '0';
if (sclk'event and sclk='1') then
sda <= '0';
m_state<=read_write;
end if;
--------------------------------------------ack ra mifrestad va khaneye hafeze ra dar data_in gharar midahad
when read_write => if (clk'event and clk='1') then
if sl_shiftreg_adr(0)='0' then m_state<= write; sda<='z';
elsif sl_shiftreg_adr(0)='1' then m_state<= read;
end if;
end if;
--------------------------------------------tashkhise read o write
when write => if (clk'event and clk='1') then
sl_shiftreg_dat<=(others=>'0');
sl_datcnt <= 8;
m_state<= rcv_data;
end if;

when rcv_data => if sl_datcnt=0 then
if clk'event and clk='1' then
m_state <=send_ack;
sda<='z';
clkcnt<=7;
--if bytenum=2 then
-- mem_out2 <=sl_shiftreg_dat;
--elsif bytenum=1 then
mem_out(j) <= sl_shiftreg_dat;
j<=j+1;
--bytenum<=2;
--end if;
end if;
elsif(sclk'event and sclk='1') then
sl_shiftreg_dat(0)<=sda;
for i in 7 downto 1 loop
sl_shiftreg_dat(i) <= sl_shiftreg_dat(i-1);
--@@@@@@@@@@((((stop))))@@@@@@@@@@@@
ssclk <= sclk;
ssda <= sda;
dsclk <= ssclk;
dsda <= ssda;
if ssda='1' and dsda='0' then
if ssclk='1' then
m_state <= idle;
sda <= '1';
end if;
end if;
end loop;

sl_datcnt <=sl_datcnt - 1;
m_state <=rcv_data;
end if;


--------------------------------------------daryafte dade
when wait_stop_bit => if (clk'event and clk='1') then
if clkcnt=0 then m_state <= send_ack;
else
clkcnt <=clkcnt - 1;
ssclk <= sclk;
ssda <= sda;
dsclk <= ssclk;
dsda <= ssda;
if ssda='1' and dsda='0' then
if ssclk='1' then
m_state <= idle;
sda <= '1';
end if;
end if;
end if;
end if;
---@@@@@@@@@@@@@
when wait_stop_bit2 => if (clk'event and clk='1') then

clkcnt <=clkcnt - 1;
ssclk <= sclk;
ssda <= sda;
dsclk <= ssclk;
dsda <= ssda;
if ssda='1' and dsda='0' then
if ssclk='1' then
m_state <= idle;
sda <= '1';
end if;
end if;
end if;

-------------------------------------------entezar baraye daryafte stop bit
when read => if (clk'event and clk='1') then
sl_datcnt <=8;
--if bytenum=2 then
--sl_shiftreg_dat<=m2;
--elsif bytenum=1 then
sl_shiftreg_dat<=m1;
-- end if;
m_state <= send_data;
end if;
when send_data =>
if(sclk'event and sclk='0') then
sda <= sl_shiftreg_dat(7);
for i in 7 downto 1 loop
sl_shiftreg_dat(i) <= sl_shiftreg_dat(i-1);
end loop;
sl_shiftreg_dat(0) <='0';
sl_datcnt <=sl_datcnt - 1;
if sl_datcnt=0 then sda <= '1'; clkcnt<=5;
m_state<=wait_ack_sl;
sda<='z';
if bytenum<=num then bytenum<=bytenum+1; end if;
else
m_state<= send_data;
end if;
end if;
--------------------------------
when wait_ack_sl =>
if sclk'event and sclk='1' then
if sda='0' then m_state <= read;

else
m_state<= wait_ack_sl;

end if;
end if;

-----------------------------ersale dade


end case;




case m2_state is

when st1 => if (clk'event and clk='1') then
sclk<='0';
m2_state <= st2;
end if;
when st2 =>
if (clk'event and clk='1') then
sclk <='1';
m2_state <= st1;
end if;
when idle =>
a <='0';
end case;

end process;
end Gate_level;


-----------------------------
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
47,447
Helped
14,038
Reputation
28,329
Reaction score
12,687
Trophy points
1,393
Location
Bochum, Germany
Activity points
275,962
I would be curious to hear the exact error message. Altera Quartus generates a lot of errors like this one
Error (10818): Can't infer register for "rd1_wr2[12]" at i2c_master.vhd(127) because it does not hold its value outside the clock edge
It's because you have multiple edge-sensitive blocks that are attempting to write to the same signal. This construct apparently works in simulation (I never tried) but isn't synthezisable. To infer flip-flops, only a single edge-sensitive condition and optionally an asynchronous set or reset are allowed to write to a signal.

This means, you can't place multiple edge-sensitive expressions in the case structure of a state machine. You can e.g. place the complete case structure under the edge-sensitive condition. I suggest to study text book examples and design templates for state machines to learn about synthesizable constructs.

Using the bidirectional SCK line as clock input to the state machine also isn't a good idea in my opinion. I noticed, that you are driving I2C lines actively high in some places, which isn't correct according to the I2C specification. I guess, it's no "Hs" mode interface.
 
Last edited:

gholamzadeh

Newbie level 4
Joined
Jun 7, 2011
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,414
thank u about ur opinion...but i don't understand exactly what u said....
master for data transmitting put data on falling edge of sck and slave read data on rising edge of sck....and then process must be sensetive on sck.my problem is in synthesis on xilinx,i must simulate m-state and m2-state in parallel mode together but xilinx ise software have error on m2-state synthesis.
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
47,447
Helped
14,038
Reputation
28,329
Reaction score
12,687
Trophy points
1,393
Location
Bochum, Germany
Activity points
275,962
but i don't understand exactly what u said....
I'll try to focus on the basic problem. Supposed you have an edge-sensitive condition in a process:
Code:
if risisng_edge(clk) then
  registered_signal <=  some_expression;
end if;
Then a second assignment to registered_signal outside this condition causes an error in synthesis. Refer to a textbook dedicated to VHDL for synthesis.

You need to rewrite your code.
 

Status
Not open for further replies.
Toggle Sidebar

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top