Commit 771ca3df authored by Denia Bouhired-Ferrag's avatar Denia Bouhired-Ferrag

WIP Merging with simulation branch

parents e18f593d 198e95b5
--==============================================================================
-- CERN (BE-CO-HT)
-- I2C bus model
--==============================================================================
--
-- author: Theodor Stana (t.stana@cern.ch)
--
-- date of creation: 2013-11-27
--
-- version: 1.0
--
-- description:
-- A very simple I2C bus model for use in simulation, implementing the
-- wired-AND on the I2C protocol.
--
-- Masters and slaves should implement the buffers internally and connect the
-- SCL and SDA lines to the input ports of this model, as below:
-- - masters should connect to mscl_i and msda_i
-- - slaves should connect to sscl_i and ssda_i
--
-- dependencies:
--
-- references:
--
--==============================================================================
-- GNU LESSER GENERAL PUBLIC LICENSE
--==============================================================================
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version. This source is distributed in the hope that it
-- will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details. You should have
-- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--==============================================================================
-- last changes:
-- 2013-11-27 Theodor Stana File created
--==============================================================================
-- TODO: -
--==============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity i2c_bus_model is
generic
(
g_nr_masters : positive := 1;
g_nr_slaves : positive := 1
);
port
(
-- Input ports from master lines
mscl_i : in std_logic_vector(g_nr_masters-1 downto 0);
msda_i : in std_logic_vector(g_nr_masters-1 downto 0);
-- Input ports from slave lines
sscl_i : in std_logic_vector(g_nr_slaves-1 downto 0);
ssda_i : in std_logic_vector(g_nr_slaves-1 downto 0);
-- SCL and SDA line outputs
scl_o : out std_logic;
sda_o : out std_logic
);
end entity i2c_bus_model;
architecture behav of i2c_bus_model is
--==============================================================================
-- architecture begin
--==============================================================================
begin
scl_o <= '1' when (mscl_i = (mscl_i'range => '1')) and
(sscl_i = (sscl_i'range => '1')) else
'0';
sda_o <= '1' when (msda_i = (msda_i'range => '1')) and
(ssda_i = (ssda_i'range => '1')) else
'0';
end architecture behav;
--==============================================================================
-- architecture end
--==============================================================================
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- I2C master and its driver
-- https://www.ohwr.org/projects/conv-common-gw
--------------------------------------------------------------------------------
--
-- unit name: Top-level simulation of conv_common_gw
--
-- description:
--
--
--
--------------------------------------------------------------------------------
-- Copyright (c) 2010-2012 CERN / BE-CO-HT
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
--------------------------------------------------------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version. This source is distributed in the hope that it
-- will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details. You should have
-- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
entity i2c_master_and_driver is
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
-- Driver interface
ready_o : out std_logic;
start_i : in std_logic;
finish_o : out std_logic;
rdwr_i : in std_logic; -- 1: read, 0: write
slv_addr_i : in std_logic_vector(6 downto 0);
reg_addr_i : in std_logic_vector(31 downto 0);
send_val_i : in std_logic_vector(31 downto 0);
rcvd_val_o : out std_logic_vector(31 downto 0);
-- I2C interface
scl_i : in std_logic;
scl_o : out std_logic;
scl_oen : out std_logic;
sda_i : in std_logic;
sda_o : out std_logic;
sda_oen : out std_logic
);
end entity i2c_master_and_driver;
architecture arch of i2c_master_and_driver is
type t_state_i2c_mst is
(
IDLE,
I2C_ADDR, I2C_ADDR_ACK,
WB_ADDR_B0, WB_ADDR_B0_ACK,
WB_ADDR_B1, WB_ADDR_B1_ACK,
ST_OP,
RD_RESTART, RD_RESTART_ACK,
RD, RD_ACK,
WR, WR_ACK,
STO,
SUCCESS,
ERR
);
-- I2C signals
signal state_i2c_mst : t_state_i2c_mst;
signal mst_sta : std_logic;
signal mst_sto : std_logic;
signal mst_rd : std_logic;
signal mst_wr : std_logic;
signal mst_ack : std_logic;
signal mst_dat_in : std_logic_vector(7 downto 0);
signal mst_dat_out : std_logic_vector(7 downto 0);
signal mst_cmd_ack : std_logic;
signal ack_fr_slv : std_logic;
signal cnt : unsigned(2 downto 0);
signal once : boolean;
signal byte_cnt : unsigned(1 downto 0);
signal rcvd : std_logic_vector(31 downto 0);
signal send : std_logic_vector(31 downto 0);
signal rst : std_logic;
begin
rst <= not rst_n_i;
-- from general-cores/modules/wishbone/wb_i2c_master/
cmp_master : entity work.i2c_master_byte_ctrl
port map(
clk => clk_i,
rst => rst,
nReset => rst_n_i,
ena => '1',
clk_cnt => x"0005", -------------x"0027",
-- input signals
start => mst_sta,
stop => mst_sto,
read => mst_rd,
write => mst_wr,
ack_in => mst_ack,
din => mst_dat_in,
-- output signals
cmd_ack => mst_cmd_ack,
ack_out => ack_fr_slv,
i2c_busy => open,
i2c_al => open,
dout => mst_dat_out,
-- i2c lines
scl_i => scl_i,
scl_o => scl_o,
scl_oen => scl_oen,
sda_i => sda_i,
sda_o => sda_o,
sda_oen => sda_oen
);
------------------------------------------------------------------------------
-- This FSM controls the signals to the master component to implement the I2C
-- protocol defined together with ELMA. The FSM is controlled by the
-- stimuli process below
------------------------------------------------------------------------------
p_mst_fsm : process (clk_i) is
begin
if rising_edge(clk_i) then
if (rst_n_i = '0') then
state_i2c_mst <= IDLE;
mst_sta <= '0';
mst_wr <= '0';
mst_sto <= '0';
mst_rd <= '0';
mst_dat_in <= (others => '0');
mst_ack <= '0';
cnt <= (others => '0');
once <= true;
byte_cnt <= (others => '0');
rcvd <= (others => '0');
send <= (others => '0');
ready_o <= '0';
finish_o <= '0';
else
case state_i2c_mst is
when IDLE =>
if (start_i = '1') then
state_i2c_mst <= I2C_ADDR;
send <= std_logic_vector(send_val_i);
ready_o <= '0';
else
ready_o <= '1';
end if;
finish_o <= '0';
when I2C_ADDR =>
mst_sta <= '1';
mst_wr <= '1';
mst_dat_in <= slv_addr_i & '0';
if (mst_cmd_ack = '1') then
mst_sta <= '0';
mst_wr <= '0';
state_i2c_mst <= I2C_ADDR_ACK;
end if;
when I2C_ADDR_ACK =>
cnt <= cnt + 1;
if (cnt = 7) then
if (ack_fr_slv = '0') then
state_i2c_mst <= WB_ADDR_B0;
else
state_i2c_mst <= ERR;
end if;
end if;
when WB_ADDR_B0 =>
mst_wr <= '1';
mst_dat_in <= reg_addr_i(15 downto 8);
if (mst_cmd_ack = '1') then
mst_wr <= '0';
state_i2c_mst <= WB_ADDR_B0_ACK;
end if;
when WB_ADDR_B0_ACK =>
cnt <= cnt + 1;
if (cnt = 7) then
if (ack_fr_slv = '0') then
state_i2c_mst <= WB_ADDR_B1;
else
state_i2c_mst <= ERR;
end if;
end if;
when WB_ADDR_B1 =>
mst_wr <= '1';
mst_dat_in <= reg_addr_i(7 downto 0);
if (mst_cmd_ack = '1') then
mst_wr <= '0';
state_i2c_mst <= WB_ADDR_B1_ACK;
end if;
when WB_ADDR_B1_ACK =>
cnt <= cnt + 1;
if (cnt = 7) then
if (ack_fr_slv = '0') then
state_i2c_mst <= ST_OP;
else
state_i2c_mst <= ERR;
end if;
end if;
when ST_OP =>
if (rdwr_i = '1') then
state_i2c_mst <= RD_RESTART;
else
state_i2c_mst <= WR;
end if;
when RD_RESTART =>
mst_wr <= '1';
mst_dat_in <= slv_addr_i & '1';
mst_sta <= '1';
if (mst_cmd_ack = '1') then
mst_sta <= '0';
mst_wr <= '0';
state_i2c_mst <= RD_RESTART_ACK;
end if;
when RD_RESTART_ACK =>
cnt <= cnt + 1;
if (cnt = 7) then
if (ack_fr_slv = '0') then
state_i2c_mst <= RD;
rcvd <= (others => '0');
else
state_i2c_mst <= ERR;
end if;
end if;
when RD =>
mst_rd <= '1';
mst_ack <= '0';
if (byte_cnt = 3) then
mst_ack <= '1';
end if;
if (mst_cmd_ack = '1') then
mst_rd <= '0';
byte_cnt <= byte_cnt + 1;
rcvd <= mst_dat_out & rcvd(31 downto 8);
mst_ack <= '0';
state_i2c_mst <= RD;
if (byte_cnt = 3) then
state_i2c_mst <= STO;
end if;
end if;
when RD_ACK =>
cnt <= cnt + 1;
if (cnt = 7) then
byte_cnt <= byte_cnt + 1;
rcvd <= mst_dat_out & rcvd(31 downto 8);
mst_ack <= '0';
state_i2c_mst <= RD;
if (byte_cnt = 3) then
state_i2c_mst <= STO;
end if;
end if;
when WR =>
mst_wr <= '1';
mst_dat_in <= send(7 downto 0);
if (mst_cmd_ack = '1') then
mst_wr <= '0';
state_i2c_mst <= WR_ACK;
end if;
when WR_ACK =>
cnt <= cnt + 1;
if (cnt = 7) then
if (ack_fr_slv = '0') then
byte_cnt <= byte_cnt + 1;
send <= x"00" & send(31 downto 8);
state_i2c_mst <= WR;
if (byte_cnt = 3) then
state_i2c_mst <= STO;
end if;
else
state_i2c_mst <= ERR;
end if;
end if;
when STO =>
mst_sto <= '1';
if (mst_cmd_ack = '1') then
mst_sto <= '0';
state_i2c_mst <= IDLE;
end if;
finish_o <= '1';
when ERR =>
if (once) then
report("Error!");
once <= false;
end if;
when others =>
state_i2c_mst <= ERR;
end case;
end if;
end if;
end process p_mst_fsm;
rcvd_val_o <= rcvd;
end architecture arch;
---------------------------------------------------------------
-- Title : Print Package
-- Project : none
---------------------------------------------------------------
-- File : print_pkg.vhd
-- Author : Michael Miehling
-- Email : miehling@men.de
-- Organization : MEN Mikroelektronik Nuernberg GmbH
-- Created : 26/08/03
---------------------------------------------------------------
-- Simulator :
-- Synthesis :
---------------------------------------------------------------
-- Description :
--
-- several procedures and functions for screen printing
---------------------------------------------------------------
-- Hierarchy:
--
-- none
---------------------------------------------------------------
-- Copyright (C) 2001, MEN Mikroelektronik Nuernberg GmbH
--
-- All rights reserved. Reproduction in whole or part is
-- prohibited without the written permission of the
-- copyright owner.
---------------------------------------------------------------
-- History
---------------------------------------------------------------
-- $Revision: 1.9 $
--
-- $Log: print_pkg.vhd,v $
-- Revision 1.9 2015/11/12 14:57:26 AGeissler
-- R1: Missing now procedure with one string
-- M1: Overload existing print_now_s with sting instead of integer
--
-- Revision 1.8 2015/11/12 13:56:46 AGeissler
-- R1: Missing character to std_logic_vector conversion function
-- M1: Added functions std_logic_vector_to_char and char_to_std_logic_vector
-- R2: Missing now procedures
-- M2: Added for each procedure a equivalent one, with an additional time print
--
-- Revision 1.7 2015/11/12 11:04:50 AGeissler
-- R1: The user shall decide, when and if spaces are used
-- M1: Removed spaces from print procedures
--
-- Revision 1.6 2015/03/10 10:20:34 AGeissler
-- R1: Improvement
-- M1.1: Added overloaded function for print_s_hb, print_s_hw, print_s_hl with std_logic_vector as parameter
-- M1.2: Replaced print_s_bit with print_s_std as a overloaded function with a std_logic as parameter
-- M1.3: Added short description for each function
--
-- Revision 1.5 2015/03/10 09:25:56 AGeissler
-- R1: Missing function to print an single bit
-- M1: Added function print_s_bit
--
-- Revision 1.4 2014/12/02 17:27:10 AGeissler
-- R1: Missing print functions for integer in hex with different sizes
-- M1: Added print functions print_s_hb, print_s_hw, print_s_hl
--
-- Revision 1.3 2014/11/24 11:26:00 AGeissler
-- R1: Missing function to print two strings for example text + time
-- (print_s(" it took ", time'image(tmp_time));)
-- M1: Added procedure print_s
--
-- Revision 1.2 2006/03/01 09:34:09 mmiehling
-- added print_now_s
--
-- Revision 1.1 2005/10/20 10:42:26 mmiehling
-- Initial Revision
--
-- Revision 1.1 2005/09/15 12:05:59 MMiehling
-- Initial Revision
--
-- Revision 1.2 2004/05/13 14:22:49 MMiehling
-- multifunction device support
--
-- Revision 1.1 2004/04/14 09:42:28 MMiehling
-- Initial Revision
--
--
---------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_textio.all;
USE ieee.numeric_std.all;
LIBRARY std;
USE std.textio.all;
PACKAGE print_pkg IS
PROCEDURE print_mtest ( source : string;
address : std_logic_vector;
is_data : std_logic_vector;
should_data : std_logic_vector;
arg : boolean);
PROCEDURE print (s: IN string);
PROCEDURE print_s (s: IN string; s2: IN string);
PROCEDURE print_s_s (s: IN string; s2: IN string; s3: IN string);
PROCEDURE print_s_i (s: IN string; s2: IN integer);
PROCEDURE print_s_h (s: IN string; s2: IN integer);
PROCEDURE print_s_hb (s: IN string; s2: IN integer);
PROCEDURE print_s_hw (s: IN string; s2: IN integer);
PROCEDURE print_s_hl (s: IN string; s2: IN integer);
PROCEDURE print_s_hb (s: IN string; s2: IN std_logic_vector(7 DOWNTO 0));
PROCEDURE print_s_hw (s: IN string; s2: IN std_logic_vector(15 DOWNTO 0));
PROCEDURE print_s_hl (s: IN string; s2: IN std_logic_vector(31 DOWNTO 0));
PROCEDURE print_s_dl (s: IN string; s2: IN std_logic_vector);
PROCEDURE print_cycle ( header : string;
address : std_logic_vector;
data : std_logic_vector;
sel_o_int : std_logic_vector(3 DOWNTO 0);
ende : string);
PROCEDURE print_s_std (s: IN string; bit: IN std_logic);
PROCEDURE print_s_std (s: IN string; vec: IN std_logic_vector);
PROCEDURE print_time (s: IN string);
PROCEDURE print_sum (intext: IN string; mstr_err: IN integer; wb_err: IN integer);
-- now procedures
PROCEDURE print_now (s: IN string);
PROCEDURE print_now_s (s: IN string; s2: IN integer);
PROCEDURE print_now_s (s: IN string; s2: IN string);
PROCEDURE print_now_s_s (s: IN string; s2: IN string; s3: IN string);
PROCEDURE print_now_s_i (s: IN string; s2: IN integer);
PROCEDURE print_now_s_h (s: IN string; s2: IN integer);
PROCEDURE print_now_s_hb (s: IN string; s2: IN integer);
PROCEDURE print_now_s_hw (s: IN string; s2: IN integer);
PROCEDURE print_now_s_hl (s: IN string; s2: IN integer);
PROCEDURE print_now_s_hb (s: IN string; s2: IN std_logic_vector(7 DOWNTO 0));
PROCEDURE print_now_s_hw (s: IN string; s2: IN std_logic_vector(15 DOWNTO 0));
PROCEDURE print_now_s_hl (s: IN string; s2: IN std_logic_vector(31 DOWNTO 0));
PROCEDURE print_now_s_dl (s: IN string; s2: IN std_logic_vector);
PROCEDURE print_now_s_std (s: IN string; bit: IN std_logic);
PROCEDURE print_now_s_std (s: IN string; vec: IN std_logic_vector);
PROCEDURE print_now_s_std_s_std (s1: IN string; vec1: IN std_logic_vector;s2: IN string; vec2: IN std_logic_vector);
PROCEDURE print_now_s_std_s(s1: IN string; vec1: IN std_logic_vector;s2: IN string);
FUNCTION char_to_std_logic_vector(arg : character) RETURN std_logic_vector;
FUNCTION std_logic_vector_to_char(arg : std_logic_vector(7 DOWNTO 0)) RETURN character;
END print_pkg;
PACKAGE BODY print_pkg IS
----------------------------------------------------------------------------------------------------------------------------------------
-- print a string with the current simulation time
PROCEDURE print_time(s: IN string) IS
VARIABLE l: line;
BEGIN
WRITE(l,now, justified=>right,field =>10, unit=> ns );
WRITE(l, string'(" "));
WRITE(l, s);
WRITELINE(output,l);
END print_time;
----------------------------------------------------------------------------------------------------------------------------------------
-- print a string and a std_logic
PROCEDURE print_s_std(s: IN string; bit: IN std_logic) IS
VARIABLE l: line;
VARIABLE s2: string(1 TO 3);
BEGIN
WRITE(l, s);
IF bit = '1' THEN
s2 := "'1'";
ELSE
s2 := "'0'";
END IF;
WRITE(l, s2);
WRITELINE(output,l);
END print_s_std;
----------------------------------------------------------------------------------------------------------------------------------------
-- print a string and a std_logic_vector as a hexadecimal number
PROCEDURE print_s_std(s: IN string; vec: IN std_logic_vector) IS
VARIABLE l: line;
BEGIN
WRITE(l, s);
HWRITE(l, vec);
WRITELINE(output,l);
END print_s_std;
----------------------------------------------------------------------------------------------------------------------------------------
-- print wishbone information
PROCEDURE print_cycle( header : string;
address : std_logic_vector;
data : std_logic_vector;
sel_o_int: std_logic_vector(3 DOWNTO 0);
ende : string) IS
VARIABLE l : line;
BEGIN
WRITE(l,header);
WRITE(l,string'(" "));
WRITE(l,now, justified=>right,field =>10, unit=> ns );
WRITE(l,string'(" ADR: "));
HWRITE(l,address,justified=>left);
WRITE(l,string'(" DATA: "));
IF address(1) = '0' THEN
CASE sel_o_int IS
WHEN "1111" => HWRITE(l,data);
WHEN "0001" => HWRITE(l,data(7 DOWNTO 0));
WRITE(l,string'(" "));
WHEN "0010" => HWRITE(l,data(15 DOWNTO 8));
WRITE(l,string'(" "));
WHEN "0100" => HWRITE(l,data(23 DOWNTO 16));
WRITE(l,string'(" "));
WHEN "1000" => HWRITE(l,data(31 DOWNTO 24));
WRITE(l,string'(" "));
WHEN "0011" => HWRITE(l,data(15 DOWNTO 0));
WRITE(l,string'(" "));
WHEN "1100" => HWRITE(l,data(31 DOWNTO 16));
WRITE(l,string'(" "));
WHEN OTHERS => ASSERT FALSE REPORT "PRINT_PKG Error: sel_o is undefined" SEVERITY error;
END CASE;
ELSE
HWRITE(l,data);
END IF;
WRITE(l,string'(" "));
WRITE(l,ende);
WRITELINE(output,l);
END print_cycle;
----------------------------------------------------------------------------------------------------------------------------------------
-- print the result of a memory test
PROCEDURE print_mtest( source : string;
address : std_logic_vector;
is_data : std_logic_vector;
should_data : std_logic_vector;
arg : boolean) IS
VARIABLE tranx : line;
BEGIN
WRITE(tranx,source);
WRITE(tranx,now, justified=>right,field =>10, unit=> ns );
WRITE(tranx,string'(" Memory Test "));
WRITE(tranx,string'(" ADR: "));
HWRITE(tranx,address,justified=>left);
IF NOT arg THEN
WRITE(tranx,string'(" DATA should be: "));
HWRITE(tranx,should_data);
WRITE(tranx, string'(" is "));
ELSE
WRITE(tranx,string'(" DATA: "));
END IF;
HWRITE(tranx,is_data);
WRITE(tranx,string'(" "));
IF arg THEN
WRITE(tranx,string'("OK"));
ELSE
WRITE(tranx,string'("ERROR!"));
END IF;
WRITELINE(output,tranx);
END print_mtest;
----------------------------------------------------------------------------------------------------------------------------------------
-- print string
PROCEDURE print(s: IN string) IS
VARIABLE l: line;
BEGIN
WRITE(l, s);
WRITELINE(output,l);
END print;
----------------------------------------------------------------------------------------------------------------------------------------
-- print two strings (for example to print string and time = print_s(" it took ", time'image(tmp_time));
PROCEDURE print_s(s: IN string;s2: IN string) IS
VARIABLE l: line;
BEGIN
WRITE(l, s);
WRITE(l, s2);
WRITELINE(output,l);
END print_s;
----------------------------------------------------------------------------------------------------------------------------------------
-- print three strings (for example to print string, value and type = print_s(" it took ", integer, "ns");
PROCEDURE print_s_s(s: IN string; s2: IN string; s3: IN string) IS
VARIABLE l: line;
BEGIN
WRITE(l, s);
WRITE(l, s2);
WRITE(l, s3);
WRITELINE(output,l);
END print_s_s;
----------------------------------------------------------------------------------------------------------------------------------------
-- print a integer as a decimal number
PROCEDURE print_s_i(s: IN string;s2: IN integer) IS
VARIABLE l: line;
BEGIN
WRITE(l, s);
WRITE(l, s2);
WRITELINE(output,l);
END print_s_i;
----------------------------------------------------------------------------------------------------------------------------------------