Line 35... |
Line 35... |
---- ----
|
---- ----
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
|
|
-- CVS Log
|
-- CVS Log
|
--
|
--
|
-- $Id: i2c_master_top.vhd,v 1.2 2001-11-10 10:52:44 rherveille Exp $
|
-- $Id: i2c_master_top.vhd,v 1.3 2002-11-30 22:24:37 rherveille Exp $
|
--
|
--
|
-- $Date: 2001-11-10 10:52:44 $
|
-- $Date: 2002-11-30 22:24:37 $
|
-- $Revision: 1.2 $
|
-- $Revision: 1.3 $
|
-- $Author: rherveille $
|
-- $Author: rherveille $
|
-- $Locker: $
|
-- $Locker: $
|
-- $State: Exp $
|
-- $State: Exp $
|
--
|
--
|
-- Change History:
|
-- Change History:
|
-- $Log: not supported by cvs2svn $
|
-- $Log: not supported by cvs2svn $
|
|
-- Revision 1.2 2001/11/10 10:52:44 rherveille
|
|
-- Changed PRER reset value from 0x0000 to 0xffff, conform specs.
|
|
--
|
|
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_arith.all;
|
|
|
entity i2c_master_top is
|
entity i2c_master_top is
|
generic(
|
generic(
|
ARST_LVL : std_logic := '0'; -- asynchronous reset level
|
ARST_LVL : std_logic := '0' -- asynchronous reset level
|
|
|
-- Register timing parameters.
|
|
-- Last parameters in list for
|
|
-- verilog compatibility
|
|
Tcq : time := 1 ns -- Clock to output delay
|
|
);
|
);
|
port (
|
port (
|
-- wishbone signals
|
-- wishbone signals
|
wb_clk_i : in std_logic; -- master clock input
|
wb_clk_i : in std_logic; -- master clock input
|
wb_rst_i : in std_logic := '0'; -- synchronous active high reset
|
wb_rst_i : in std_logic := '0'; -- synchronous active high reset
|
Line 86... |
Line 84... |
);
|
);
|
end entity i2c_master_top;
|
end entity i2c_master_top;
|
|
|
architecture structural of i2c_master_top is
|
architecture structural of i2c_master_top is
|
component i2c_master_byte_ctrl is
|
component i2c_master_byte_ctrl is
|
generic(
|
|
Tcq : time := Tcq
|
|
);
|
|
port (
|
port (
|
clk : in std_logic;
|
clk : in std_logic;
|
rst : in std_logic; -- synchronous active high reset (WISHBONE compatible)
|
rst : in std_logic; -- synchronous active high reset (WISHBONE compatible)
|
nReset : in std_logic; -- asynchornous active low reset (FPGA compatible)
|
nReset : in std_logic; -- asynchornous active low reset (FPGA compatible)
|
ena : in std_logic; -- core enable signal
|
ena : in std_logic; -- core enable signal
|
Line 132... |
Line 127... |
signal sr : std_logic_vector(7 downto 0); -- status register
|
signal sr : std_logic_vector(7 downto 0); -- status register
|
|
|
-- internal reset signal
|
-- internal reset signal
|
signal rst_i : std_logic;
|
signal rst_i : std_logic;
|
|
|
|
-- internal acknowledge signal
|
|
signal iack_o : std_logic;
|
|
|
-- done signal: command completed, clear command register
|
-- done signal: command completed, clear command register
|
signal done : std_logic;
|
signal done : std_logic;
|
|
|
-- command register signals
|
-- command register signals
|
signal sta, sto, rd, wr, ack, iack : std_logic;
|
signal sta, sto, rd, wr, ack, iack : std_logic;
|
Line 153... |
Line 151... |
begin
|
begin
|
-- generate internal reset signal
|
-- generate internal reset signal
|
rst_i <= arst_i xor ARST_LVL;
|
rst_i <= arst_i xor ARST_LVL;
|
|
|
-- generate acknowledge output signal
|
-- generate acknowledge output signal
|
wb_ack_o <= wb_cyc_i and wb_stb_i; -- because timing is always honored
|
gen_ack_o : process(wb_clk_i)
|
|
|
-- assign wb_dat_o
|
|
assign_dato : process(wb_adr_i, prer, ctr, txr, cr, rxr, sr)
|
|
begin
|
begin
|
case wb_adr_i is
|
if (wb_clk_i'event and wb_clk_i = '1') then
|
when "000" =>
|
iack_o <= wb_cyc_i and wb_stb_i and not iack_o; -- because timing is always honored
|
wb_dat_o <= std_logic_vector(prer( 7 downto 0));
|
end if;
|
|
end process gen_ack_o;
|
when "001" =>
|
|
wb_dat_o <= std_logic_vector(prer(15 downto 8));
|
|
|
|
when "010" =>
|
wb_ack_o <= iack_o;
|
wb_dat_o <= ctr;
|
|
|
|
when "011" =>
|
|
wb_dat_o <= rxr; -- write is transmit register TxR
|
|
|
|
when "100" =>
|
-- assign wb_dat_o
|
wb_dat_o <= sr; -- write is command register CR
|
assign_dato : process(wb_clk_i)
|
|
begin
|
|
if (wb_clk_i'event and wb_clk_i = '1') then
|
|
case wb_adr_i is
|
|
when "000" => wb_dat_o <= std_logic_vector(prer( 7 downto 0));
|
|
when "001" => wb_dat_o <= std_logic_vector(prer(15 downto 8));
|
|
when "010" => wb_dat_o <= ctr;
|
|
when "011" => wb_dat_o <= rxr; -- write is transmit register TxR
|
|
when "100" => wb_dat_o <= sr; -- write is command register CR
|
|
|
-- Debugging registers:
|
-- Debugging registers:
|
-- These registers are not documented.
|
-- These registers are not documented.
|
-- Functionality could change in future releases
|
-- Functionality could change in future releases
|
|
when "101" => wb_dat_o <= txr;
|
when "101" =>
|
when "110" => wb_dat_o <= cr;
|
wb_dat_o <= txr;
|
when "111" => wb_dat_o <= (others => '0');
|
|
when others => wb_dat_o <= (others => 'X'); -- for simulation only
|
when "110" =>
|
|
wb_dat_o <= cr;
|
|
|
|
when "111" =>
|
|
wb_dat_o <= (others => '0');
|
|
|
|
when others =>
|
|
wb_dat_o <= (others => 'X'); -- for simulation only
|
|
|
|
end case;
|
end case;
|
|
end if;
|
end process assign_dato;
|
end process assign_dato;
|
|
|
|
|
-- registers block
|
-- registers block
|
regs_block: process(rst_i, wb_clk_i)
|
regs_block: process(rst_i, wb_clk_i)
|
begin
|
begin
|
if (rst_i = '0') then
|
if (rst_i = '0') then
|
prer <= (others => '1') after Tcq;
|
prer <= (others => '1');
|
ctr <= (others => '0') after Tcq;
|
ctr <= (others => '0');
|
txr <= (others => '0') after Tcq;
|
txr <= (others => '0');
|
cr <= (others => '0') after Tcq;
|
cr <= (others => '0');
|
elsif (wb_clk_i'event and wb_clk_i = '1') then
|
elsif (wb_clk_i'event and wb_clk_i = '1') then
|
if (wb_rst_i = '1') then
|
if (wb_rst_i = '1') then
|
prer <= (others => '1') after Tcq;
|
prer <= (others => '1');
|
ctr <= (others => '0') after Tcq;
|
ctr <= (others => '0');
|
txr <= (others => '0') after Tcq;
|
txr <= (others => '0');
|
cr <= (others => '0') after Tcq;
|
cr <= (others => '0');
|
else
|
else
|
if (wb_cyc_i = '1' and wb_stb_i = '1' and wb_we_i = '1') then
|
if (wb_cyc_i = '1' and wb_stb_i = '1' and wb_we_i = '1') then
|
if (wb_adr_i(2) = '0') then
|
if (wb_adr_i(2) = '0') then
|
case wb_adr_i(1 downto 0) is
|
case wb_adr_i(1 downto 0) is
|
when "00" => prer( 7 downto 0) <= unsigned(wb_dat_i) after Tcq;
|
when "00" => prer( 7 downto 0) <= unsigned(wb_dat_i);
|
when "01" => prer(15 downto 8) <= unsigned(wb_dat_i) after Tcq;
|
when "01" => prer(15 downto 8) <= unsigned(wb_dat_i);
|
when "10" => ctr <= wb_dat_i after Tcq;
|
when "10" => ctr <= wb_dat_i;
|
when "11" => txr <= wb_dat_i after Tcq;
|
when "11" => txr <= wb_dat_i;
|
|
|
-- illegal cases, for simulation only
|
-- illegal cases, for simulation only
|
when others =>
|
when others =>
|
report ("Illegal write address, setting all registers to unknown.");
|
report ("Illegal write address, setting all registers to unknown.");
|
prer <= (others => 'X');
|
prer <= (others => 'X');
|
Line 227... |
Line 217... |
txr <= (others => 'X');
|
txr <= (others => 'X');
|
end case;
|
end case;
|
elsif ( (core_en = '1') and (wb_adr_i(1 downto 0) = 0) ) then
|
elsif ( (core_en = '1') and (wb_adr_i(1 downto 0) = 0) ) then
|
-- only take new commands when i2c ore enabled
|
-- only take new commands when i2c ore enabled
|
-- pending commands are finished
|
-- pending commands are finished
|
cr <= wb_dat_i after Tcq;
|
cr <= wb_dat_i;
|
end if;
|
end if;
|
else
|
else
|
-- clear command bits when done
|
-- clear command bits when done
|
if (done = '1') then
|
if (done = '1') then
|
cr(7 downto 4) <= (others => '0') after Tcq;
|
cr(7 downto 4) <= (others => '0');
|
end if;
|
end if;
|
|
|
-- reserved bits
|
-- reserved bits
|
cr(2 downto 1) <= (others => '0') after Tcq;
|
cr(2 downto 1) <= (others => '0');
|
|
|
-- clear iack when irq_flag cleared
|
-- clear iack when irq_flag cleared
|
cr(0) <= cr(0) and irq_flag;
|
cr(0) <= cr(0) and irq_flag;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process regs_block;
|
end process regs_block;
|
|
|
|
|
-- decode command register
|
-- decode command register
|
sta <= cr(7);
|
sta <= cr(7);
|
sto <= cr(6);
|
sto <= cr(6);
|
rd <= cr(5);
|
rd <= cr(5);
|
wr <= cr(4);
|
wr <= cr(4);
|
Line 290... |
Line 281... |
begin
|
begin
|
-- generate status register bits
|
-- generate status register bits
|
gen_sr_bits: process (wb_clk_i, rst_i)
|
gen_sr_bits: process (wb_clk_i, rst_i)
|
begin
|
begin
|
if (rst_i = '0') then
|
if (rst_i = '0') then
|
rxack <= '0' after Tcq;
|
rxack <= '0';
|
tip <= '0' after Tcq;
|
tip <= '0';
|
irq_flag <= '0' after Tcq;
|
irq_flag <= '0';
|
elsif (wb_clk_i'event and wb_clk_i = '1') then
|
elsif (wb_clk_i'event and wb_clk_i = '1') then
|
if (wb_rst_i = '1') then
|
if (wb_rst_i = '1') then
|
rxack <= '0' after Tcq;
|
rxack <= '0';
|
tip <= '0' after Tcq;
|
tip <= '0';
|
irq_flag <= '0' after Tcq;
|
irq_flag <= '0';
|
else
|
else
|
rxack <= irxack after Tcq;
|
rxack <= irxack;
|
tip <= (rd or wr) after Tcq;
|
tip <= (rd or wr);
|
|
|
-- interrupt request flag is always generated
|
-- interrupt request flag is always generated
|
irq_flag <= (done or irq_flag) and not iack after Tcq;
|
irq_flag <= (done or irq_flag) and not iack;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process gen_sr_bits;
|
end process gen_sr_bits;
|
|
|
-- generate interrupt request signals
|
-- generate interrupt request signals
|
gen_irq: process (wb_clk_i, rst_i)
|
gen_irq: process (wb_clk_i, rst_i)
|
begin
|
begin
|
if (rst_i = '0') then
|
if (rst_i = '0') then
|
wb_inta_o <= '0' after Tcq;
|
wb_inta_o <= '0';
|
elsif (wb_clk_i'event and wb_clk_i = '1') then
|
elsif (wb_clk_i'event and wb_clk_i = '1') then
|
if (wb_rst_i = '1') then
|
if (wb_rst_i = '1') then
|
wb_inta_o <= '0' after Tcq;
|
wb_inta_o <= '0';
|
else
|
else
|
-- interrupt signal is only generated when IEN (interrupt enable bit) is set
|
-- interrupt signal is only generated when IEN (interrupt enable bit) is set
|
wb_inta_o <= irq_flag and ien after Tcq;
|
wb_inta_o <= irq_flag and ien;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process gen_irq;
|
end process gen_irq;
|
|
|
-- assign status register bits
|
-- assign status register bits
|
Line 333... |
Line 324... |
sr(0) <= irq_flag;
|
sr(0) <= irq_flag;
|
end block;
|
end block;
|
|
|
end architecture structural;
|
end architecture structural;
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|