Commit 7bc7f4f0 authored by gilsoriano's avatar gilsoriano

Restructured CTDAH in a proper way:

- Creation of a "hdl/ctdah_pkg: which share common components used along the design.
- Creation of m24p32 HDL core for managing access to m25p32 memory.
--- m24p32 is better structured by using packages, records and fucntions for easy translation.
- Creation of "hdl/spi_master_multified" for communicating with m24p32
- Modification "hdl/i2c_slave_wb_master" for better readability.
parent e06b805e
----------------------------------------------------------------------------------
-- Company: CERN, BE-CO-HT
-- Engineer: Carlos Gil Soriano
--
-- Create Date: 18:28:55 11/08/2011
-- Design Name: FIFO dispatcher with parallel load
-- Module Name: FIFO_dispatcher - Behavioral
-- Project Name: CTDAH
-- Target Devices: Spartan 6
-- Tool versions:
-- Description: This is a FIFO dispathcher with parallel load and flush.
--
-- | |
-- |----------|
-- reg_i LSB ---> | REG 0 |
-- |----------|
-- ---> | REG 1 |
-- |----------|
-- ---> | REG 2 |
-- |----------|
-- reg_i MSB ---> | REG 3 | ---> reg_o
-- |__________|
--
-- Dependencies: none
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity FIFO_dispatcher is
generic(
g_data_width : NATURAL := 8;
g_dispatcher_depth : NATURAL := 4
);
port (
reg_i : in STD_LOGIC_VECTOR (g_dispatcher_depth*g_data_width-1 downto 0);
clk : in STD_LOGIC;
load : in STD_LOGIC;
flush : in STD_LOGIC;
oen_i : in STD_LOGIC;
reg_o : out STD_LOGIC_VECTOR (g_data_width - 1 downto 0)
);
end FIFO_dispatcher;
architecture Behavioral of FIFO_dispatcher is
type DISPATCHER_REG is array(0 to g_dispatcher_depth-1) of STD_LOGIC_VECTOR(g_data_width - 1 downto 0);
signal reg_int : DISPATCHER_REG;
begin
process(clk, flush)
begin
if flush = '1' then
flushLoop: for i in 0 to g_dispatcher_depth-1 loop
reg_int(i) <= (others => '0');
end loop;
elsif rising_edge(clk) then
if load = '1' then
loadLoop: for i in 0 to g_dispatcher_depth - 1 loop
reg_int(i) <= reg_i((i+1)*g_data_width - 1 downto i*g_data_width) ;
end loop;
else
end if;
if oen_i = '1' then
reg_o <= reg_int(g_dispatcher_depth -1);
for i in 0 to g_dispatcher_depth - 2 loop
reg_int(i+1) <= reg_int(i);
end loop;
reg_int(0) <= (others => '0');
else
end if;
else
end if;
end process;
end Behavioral;
----------------------------------------------------------------------------------
-- Company: CERN, BE-CO-HT
-- Engineer: Carlos Gil Soriano
--
-- Create Date: 10:33:33 11/08/2011
-- Design Name: FIFO variable stack length
-- Module Name: FIFO_stack - Behavioral
-- Project Name: CTDAH
-- Target Devices: Spartan 6
-- Tool versions:
-- Description: This module implements a generic FIFO stack of variable
-- data input length and stack depth. The ASCII art represents
-- the behaviour of the module, which works as a g_stack_depth
-- delay with parallel output
--
-- input--->
-- | |
-- |----------|
-- | REG 0 | ---> reg_o LSB
-- |----------|
-- | REG 1 | --->
-- |----------|
-- | REG 2 | --->
-- |----------|
-- | REG 3 | ---> reg_o MSB
-- |__________|
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity FIFO_stack is
generic(
g_data_width : NATURAL := 8;
g_stack_depth : NATURAL := 8
);
port (
reg_i : in STD_LOGIC_VECTOR (g_data_width-1 downto 0);
clk : in STD_LOGIC;
push : in STD_LOGIC;
flush : in STD_LOGIC;
reg_o : out STD_LOGIC_VECTOR (g_stack_depth*g_data_width - 1 downto 0)
);
end FIFO_stack;
architecture Behavioral of FIFO_stack is
type FIFO_REG is array(0 to g_stack_depth-1) of std_logic_vector(g_data_width - 1 downto 0);
signal reg_int : FIFO_REG;
begin
reg_o((g_stack_depth)*g_data_width-1 downto (g_stack_depth-1)*g_data_width ) <= reg_int(g_stack_depth-1);
gen_out: for i in 0 to g_stack_depth-2 generate
reg_o((i+1)*g_data_width-1 downto i*g_data_width ) <= reg_int(i);
end generate gen_out;
reg_proc: process(clk)
begin
if rising_edge(clk) then
if flush = '1' then
for i in 0 to g_stack_depth-1 loop
reg_int(i) <= (others => '0');
end loop;
elsif push = '1' then
reg_int(0) <= reg_i;
for i in 0 to g_stack_depth-2 loop
reg_int(i+1) <= reg_int(i);
end loop;
else
end if;
end if;
end process;
end Behavioral;
--
-- Package File Template
--
-- Purpose: This package defines supplemental types, subtypes,
-- constants, and functions
--
-- To use any of the example code shown below, uncomment the lines and modify as necessary
--
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package ctdah_pkg is
component gc_counter is
generic(
g_data_width: NATURAL
);
port (
clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC;
en_i : in STD_LOGIC;
cnt_o : out STD_LOGIC_VECTOR (g_data_width-1 downto 0)
);
end component;
component gc_ff is
port(
Q : out STD_LOGIC;
C : in STD_LOGIC;
CLR : in STD_LOGIC;
D : in STD_LOGIC
);
end component;
component FIFO_dispatcher is
generic(
g_data_width : NATURAL := 8;
g_dispatcher_depth : NATURAL := 4
);
port (
reg_i : in STD_LOGIC_VECTOR (g_dispatcher_depth*g_data_width-1 downto 0);
clk : in STD_LOGIC;
load : in STD_LOGIC;
flush : in STD_LOGIC;
oen_i : in STD_LOGIC;
reg_o : out STD_LOGIC_VECTOR (g_data_width - 1 downto 0)
);
end component;
component FIFO_stack is
generic(
g_data_width : NATURAL := 8;
g_stack_depth : NATURAL := 8
);
port (
reg_i : in STD_LOGIC_VECTOR (g_data_width-1 downto 0);
clk : in STD_LOGIC;
push : in STD_LOGIC;
flush : in STD_LOGIC;
reg_o : out STD_LOGIC_VECTOR (g_stack_depth*g_data_width - 1 downto 0)
);
end component;
end ctdah_pkg;
package body ctdah_pkg is
end ctdah_pkg;
-------------------------------------------------------------------------------
-- Title : Counter with asynchronous reset
-- Project : CTDAH
-------------------------------------------------------------------------------
-- File : gc_counter.vhd
-- Author : Carlos Gil Soriano
-- Company : CERN BE-CO-HT
-- Created : 2011-07-11
-- Last update: 2011-07-11
-- Platform : FPGA-generic
-- Standard : VHDL '87
------------------------------------------------------------------------------
-- Description: Counter with asynchronous reset
-------------------------------------------------------------------------------
--
-- Copyright (c) 2009 - 2010 CERN
--
-- 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
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-07-11 1.0 gilsoriano Created
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity gc_counter is
generic(
g_data_width: NATURAL
);
port (
clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC;
en_i : in STD_LOGIC;
cnt_o : out STD_LOGIC_VECTOR (g_data_width-1 downto 0)
);
end gc_counter;
architecture Behavioral of gc_counter is
begin
main_proc: process(clk_i, rst_i)
variable cnt_s : UNSIGNED(g_data_width-1 downto 0);
begin
if rst_i = '1' then
cnt_s := (others => '0');
elsif rising_edge(clk_i) then
if en_i = '1' then
-- Increment the counter if counting is enabled
cnt_s := cnt_s + 1;
else
end if;
else
end if;
cnt_o <= std_logic_vector(cnt_s);
end process;
end Behavioral;
----------------------------------------------------------------------------------
-- Company: CERN
-- Engineer: Carlos Gil Soriano
--
-- Create Date: 16:26:32 10/07/2011
-- Design Name: Basic debouncer
-- Module Name: debouncer - Behavioral
-- Project Name: CTDAH
-- Target Devices: Spartan 6
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity gc_ff is
port(
Q : out STD_LOGIC;
C : in STD_LOGIC;
CLR : in STD_LOGIC;
D : in STD_LOGIC
);
end gc_ff;
architecture Behavioral of gc_ff is
begin
reg_proc: process(C)
begin
if rising_edge(C) then
if CLR = '1' then
Q <= '0';
else
Q <= D;
end if;
else
end if;
end process;
end Behavioral;
......@@ -22,9 +22,10 @@
--
----------------------------------------------------------------------------------
library IEEE;
library work;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.ctdah_pkg.ALL;
entity i2c_bit is
port (
......@@ -65,17 +66,6 @@ architecture Behavioral of i2c_bit is
);
end component;
component gc_ff
port(
Q : out STD_LOGIC;
C : in STD_LOGIC;
CLR : in STD_LOGIC;
D : in STD_LOGIC
);
end component;
signal s_sda_dGLITCH : STD_LOGIC;
signal s_sda_dGLITCH_d1 : STD_LOGIC;
signal s_scl_dGLITCH : STD_LOGIC;
......
......@@ -23,8 +23,10 @@
--
----------------------------------------------------------------------------------
library IEEE;
library work;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.ctdah_pkg.ALL;
entity i2c_debouncer is
generic (
......@@ -51,15 +53,6 @@ signal delay_s : std_logic_vector(to_integer(g_LENGTH)-1 downto 0);
signal output_s : std_logic;
component gc_ff
port(
Q : out STD_LOGIC;
C : in STD_LOGIC;
CLR : in STD_LOGIC;
D : in STD_LOGIC
);
end component;
begin
......
......@@ -51,8 +51,10 @@
--
----------------------------------------------------------------------------------
library IEEE;
library work;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.ctdha_pkg.ALL;
entity i2c_slave_core is
port (
......@@ -207,18 +209,6 @@ signal s_rcved_o : STD_LOGIC;
signal s_DRX0_o : STD_LOGIC_VECTOR(7 downto 0);
signal s_i2c_addr_masked : STD_LOGIC_VECTOR(6 downto 0);
component gc_counter
generic (
g_data_width : NATURAL := c_COUNTER_WIDTH
);
port (
clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC;
en_i : in STD_LOGIC;
cnt_o : out STD_LOGIC_VECTOR(g_data_width-1 downto 0)
);
end component;
component i2c_bit
port (
rst_i : in STD_LOGIC;
......@@ -233,44 +223,6 @@ signal s_i2c_addr_masked : STD_LOGIC_VECTOR(6 downto 0);
);
end component;
component FIFO_stack
generic(
g_data_width : NATURAL := c_DATA_WIDTH;
g_stack_depth : NATURAL := c_RX_STACK_DEPTH
);
port (
reg_i : in STD_LOGIC_VECTOR (g_data_width-1 downto 0);
clk : in STD_LOGIC;
push : in STD_LOGIC;
flush : in STD_LOGIC;
reg_o : out STD_LOGIC_VECTOR (g_stack_depth*g_data_width - 1 downto 0)
);
end component;
component FIFO_dispatcher
generic(
g_data_width : NATURAL := c_DATA_WIDTH;
g_dispatcher_depth : NATURAL := c_TX_STACK_DEPTH
);
port (
reg_i : in STD_LOGIC_VECTOR (c_TX_STACK_DEPTH*c_DATA_WIDTH-1 downto 0);
clk : in STD_LOGIC;
load : in STD_LOGIC;
flush : in STD_LOGIC;
oen_i : in STD_LOGIC;
reg_o : out STD_LOGIC_VECTOR (c_DATA_WIDTH - 1 downto 0)
);
end component;
component gc_ff
port(
Q : out STD_LOGIC;
C : in STD_LOGIC;
CLR : in STD_LOGIC;
D : in STD_LOGIC
);
end component;
begin
STA_o(0) <= CTR0_i (0);
......
......@@ -19,110 +19,146 @@
--
----------------------------------------------------------------------------------
library IEEE;
library work;
use IEEE.STD_LOGIC_1164.ALL;
use work.m25p32_pkg.ALL;
entity m25p32_core is
port (
wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
prom_mosi_o : out STD_LOGIC;
prom_cclk_o : out STD_LOGIC;
prom_cso_b_n_o : out STD_LOGIC;
prom_din_o : out STD_LOGIC;
mosi_o : out STD_LOGIC;
miso_i : in STD_LOGIC;
sclk_o : out STD_LOGIC;
ss_n_o : out STD_LOGIC;
CTR0_i : in STD_LOGIC;
CTR1_i : in STD_LOGIC;
STATUS_i : in STD_LOGIC
CTR0_o : out STD_LOGIC_VECTOR(7 downto 0);
FMOH_i : in STD_LOGIC_VECTOR(31 downto 0)
);
end m25p32_core;
architecture Behavioral of m25p32_core is
component spi_master_core is
generic(
g_inst_width := 1;
g_addr_width := 3;
g_data_width := 256
); port(
rst_i : in STD_LOGIC;
clk : in STD_LOGIC
inst_i : in STD_LOGIC_VECTOR (8*g_inst_width - 1 downto 0);
addr_i : in STD_LOGIC_VECTOR (8*g_addr_width - 1 downto 0);
data_i : in STD_LOGIC_VECTOR (8*g_data_width - 1 downto 0);
push_inst_i : in STD_LOGIC;
push_addr_i : in STD_LOGIC;
push_data_i : in STD_LOGIC;
data_i : in STD_LOGIC_VECTOR (8*g_data_width - 1 downto 0);
SPI0_i : in STD_LOGIC_VECTOR (31 downto 0)
);
end component;
-------------------------------------------------------------------------------
-- WRite ENable bit
---------------------------------------
-- It must be set alwayd before the following instructions:
-- PP_inst Page Program
-- SE_inst Sector Erase
-- BE_inst Bulk Erase
-- WRSR_inst WRite Status Register
---------------------------------------
-- It works by placing:
-- 1.- Chip Select Low
-- 2.- Send instruction
-- 3.- Chip Select High
-------------------------------------------------------------------------------
constant WREN_addr : STD_LOGIC_VECTOR(7 downto 0) := X"06";
------------------------------------------------------------------------------
-- WRite DIsable bit
---------------------------------------
-- It works by placing:
-- 1.- Chip Select Low
-- 2.- Send instruction
-- 3.- Chip Select High
-------------------------------------------------------------------------------
constant WRDI_addr : STD_LOGIC_VECTOR(7 downto 0) := X"04";
------------------------------------------------------------------------------
-- ReaD Status Register
---------------------------------------
--
---------------------------------------
-- It works by placing:
-- 1.- Chip Select Low
-- 2.- Send instruction
-- 3.- Read for the following 8 clocks the serial line
-- NOTE: the RDSR register is sent twice in the serial interface, so it can
-- read the same value of the register twice.
-- 4.- Chip Select High
------------------------------------------------------------------------------
constant RDSR_addr : STD_LOGIC_VECTOR(7 downto 0) := X"05";
------------------------------------------------------------------------------
-- WRite Status Register
---------------------------------------
-- It works by placing:
-- 1.- Chip Select Low
-- 2.- Send instruction
-- 3.- Send the WRSR value
-- 4.- Chip Select High
------------------------------------------------------------------------------
constant WRSR_addr : STD_LOGIC_VECTOR(7 downto 0) := X"01";
constant READ_addr : STD_LOGIC_VECTOR(7 downto 0) := X"03";
constant FAST_READ_addr : STD_LOGIC_VECTOR(7 downto 0) := X"0B";
constant PP_addr : STD_LOGIC_VECTOR(7 downto 0) := X"02";
type t_m25p32_fsm is (S0_IDLE, S1_WREN, S2_SPI_WRITE, S3_DEL_PROG_CYCLE, S4_WRDI, Q1_ERROR);
constant SE_addr : STD_LOGIC_VECTOR(7 downto 0) := X"D8";
signal MEM_fsm : t_m25p32_fsm;
constant BE_addr : STD_LOGIC_VECTOR(7 downto 0) := X"C7";
signal s_CTR0 : r_CTR0;
signal s_FMOH : r_FMOH;
constant DP_addr : STD_LOGIC_VECTOR(7 downto 0) := X"B9";
constant RES_addr : STD_LOGIC_VECTOR(7 downto 0) := X"AB";
begin
comb_proc: process
s_FMOH <= f_FMOH(FMOH_i);
CTR0_o <= f_STD_LOGIC_VECTOR(s_CTR0);
p_out: process (wb_clk)
begin
if rising_edge(wb_clk) then
if wb_rst_i = '1' then
s_CTR0 <= c_CTR0_default;
else
if s_FMOH.OPP = '1' then
case s_FMOH.OP is
when ERS =>
case MEM_fsm is
when S0_IDLE =>
s_CTR0.OPA <= '1';
s_CTR0.OPF <= '0';
when S1_WREN =>
when S2_SPI_WRITE =>
when S3_DEL_PROG_CYCLE =>
when S4_WRDI =>
when Q1_ERROR =>
s_CTR0.OPA <= '1';
s_CTR0.OPF <= '1';
when others =>
end case;
when RDP =>
case MEM_fsm is
when S0_IDLE =>
when S1_WREN =>
when S2_SPI_WRITE =>
when S3_DEL_PROG_CYCLE =>
when S4_WRDI =>
when Q1_ERROR =>
when others =>
end case;
when WRP =>
case MEM_fsm is
when S0_IDLE =>
when S1_WREN =>
when S2_SPI_WRITE =>
when S3_DEL_PROG_CYCLE =>
when S4_WRDI =>
when Q1_ERROR =>
when others =>
end case;
when others =>
end case;
else
s_CTR0.OPA <= '0';
s_CTR0.OPF <= '0';
end if;
end if;
else
end if;
end process;
reg_proc: process (wb_clk)
p_ERS_fsm: process (wb_clk)
begin
if rising_edge(wb_clk) then
if wb_rst_i = '1' then
MEM_fsm <= S0_IDLE;
else
if s_FMOH.OPP = '1' and s_CTR0.OPA = '0' then
case s_FMOH.OP is
when ERS =>
case MEM_fsm is
when S0_IDLE =>
when S1_WREN =>
when S2_SPI_WRITE =>
when S3_DEL_PROG_CYCLE =>
when S4_WRDI =>
when Q1_ERROR =>
when others =>
end case;
when RDP =>
when WRP =>
when others =>
end case;
else
end if;
end if;
else
end if;
end process;
end Behavioral;
--
-- Package File Template
--
-- Purpose: This package defines supplemental types, subtypes,
-- constants, and functions
--
-- To use any of the example code shown below, uncomment the lines and modify as necessary
--
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.ALL;
package m25p32_pkg is
----------------------------------------
-- ConTRol 0 Register
----------------------------------------
-- 16 bits
-- Wishbone access: Read-only
----------------------------------------
-- BIT NAME DESCRIPTION
-- 0 OPA OPeration Attended
-- 1 OPF OPeration Finished
-- 7-2 x Reserved
----------------------------------------
type r_CTR0 is
record
OPA : STD_LOGIC;
OPF : STD_LOGIC;
x : STD_LOGIC_VECTOR(7 downto 2);
end record;
----------------------------------------
-- Flash Memory Operation Handler Register
----------------------------------------
-- 32 bits
-- Wishbone access: Write-read
----------------------------------------
-- BIT NAME DESCRIPTION
-- 1-0 OP OPeration
-- 2 x Reserved
-- 3 OPP OPeration Pending
-- 15-4 y Reserved
-- 23-16 PG PaGe number
-- 29-24 SCT SeCTor number
-- 31-30 z Reserved
----------------------------------------
-- List of operations:
-- 0b00 x Reserved
-- 0b01 ERS ERase sector. Sets everything to FF
-- 0b10 RDP ReaD Page. Not implemented by now.
-- 0b11 WRP WRite Page
----------------------------------------
type t_operations is (x, ERS, RDP, WRP); --It will be 2 bits
type r_FMOH is
record
OP : t_operations;
x : STD_LOGIC;
OPP : STD_LOGIC;
y : STD_LOGIC_VECTOR(15 downto 4);
PG : STD_LOGIC_VECTOR(23 downto 16);
SCT : STD_LOGIC_VECTOR(29 downto 24);
z : STD_LOGIC_VECTOR(31 downto 30);
end record;
------------------------------------------------------------------------------
-- m25p32 m25p32 m25p32 m25p32 m25p32 SPI Instruction set
------------------------------------------------------------------------------
-- INSTRUCTION DESCRIPTION ADDRESS DATA
-- BYTES BYTES
-- WREN WRite ENable 0 0
-- WRDI WRite DIsable 0 0
-- RDSR ReaD Status Register 0 1
-- WRSR WRite Status Register 0 1
-- READ READ data bytes 3 4
-- FAST_READ FAST READ data bytes 3 4
-- PP Page Program 3 256
-- SE Sector Erase 3 0
-- BE Bulk Erase 0 0
-------------------------------------------------------------------------------
constant c_WREN_inst : STD_LOGIC_VECTOR(7 downto 0) := X"06";
constant c_WRDI_inst : STD_LOGIC_VECTOR(7 downto 0) := X"04";
constant c_RDSR_inst : STD_LOGIC_VECTOR(7 downto 0) := X"05";
constant c_WRSR_inst : STD_LOGIC_VECTOR(7 downto 0) := X"01";
constant c_READ_inst : STD_LOGIC_VECTOR(7 downto 0) := X"03";
constant c_FAST_READ_inst : STD_LOGIC_VECTOR(7 downto 0) := X"0B";
constant c_PP_inst : STD_LOGIC_VECTOR(7 downto 0) := X"02";
constant c_SE_inst : STD_LOGIC_VECTOR(7 downto 0) := X"D8";
constant c_BE_inst : STD_LOGIC_VECTOR(7 downto 0) := X"C7";
constant c_CTR0_addr : STD_LOGIC_VECTOR (3 downto 0) := X"0";
constant c_FMOH_addr : STD_LOGIC_VECTOR (3 downto 0) := X"1";
constant c_CTR0_default : r_CTR0 := (OPA => '0',
OPF => '0',
x => (others => '0'));
constant c_FMOH_default : r_FMOH := (OP => t_operations'val(0),
x => '0',
OPP => '0',
y => (others => '0'),
PG => (others => '0'),
SCT => (others => '0'),
z => (others => '0'));
function f_STD_LOGIC_VECTOR (signal r_register : in r_CTR0) return STD_LOGIC_VECTOR;
function f_STD_LOGIC_VECTOR (signal r_register : in r_FMOH) return STD_LOGIC_VECTOR;
function f_CTR0 (signal r_register : in STD_LOGIC_VECTOR(7 downto 0)) return r_CTR0;
function f_FMOH (signal r_register : in STD_LOGIC_VECTOR(31 downto 0)) return r_FMOH;
-- procedure <procedure_name> (<type_declaration> <constant_name> : in <type_declaration>);
--
end m25p32_pkg;
package body m25p32_pkg is
-----------------------------------------------------------------------------
--! @brief CTR0 record type translation to STD_LOGIC_VECTOR
--! @param r_register r_CTR0 record type to be translated
-----------------------------------------------------------------------------
function f_STD_LOGIC_VECTOR (signal r_register : in r_CTR0) return STD_LOGIC_VECTOR is
begin
return (r_register.x & r_register.OPA & r_register.OPF);
end f_STD_LOGIC_VECTOR;
-----------------------------------------------------------------------------
--! @brief Translation from STD_LOGIC_VECTOR to r_CTR0 record
--! @param r_register STD_LOGIC_VECTOR to be translated
-----------------------------------------------------------------------------
function f_CTR0 (signal r_register : in STD_LOGIC_VECTOR(7 downto 0)) return r_CTR0 is
variable v_CTR0 : r_CTR0;
begin
v_CTR0.OPA := r_register(0);
v_CTR0.OPF := r_register(1);
v_CTR0.x := r_register(7 downto 2);
return v_CTR0;
end f_CTR0;
-----------------------------------------------------------------------------
--! @brief FMOH record type translation to STD_LOGIC_VECTOR
--! @param r_register r_FMOH record type to be translated
-----------------------------------------------------------------------------
function f_STD_LOGIC_VECTOR (signal r_register : in r_FMOH) return STD_LOGIC_VECTOR is
begin
return (r_register.z & r_register.SCT & r_register.PG & r_register.y & r_register.OPP
& r_register.x & std_logic_vector(to_unsigned(t_operations'pos(r_register.OP),2)) );
end f_STD_LOGIC_VECTOR;
-----------------------------------------------------------------------------
--! @brief Translation from STD_LOGIC_VECTOR to r_CTR0 record
--! @param r_register STD_LOGIC_VECTOR to be translated
-----------------------------------------------------------------------------
function f_FMOH(signal r_register : in STD_LOGIC_VECTOR(31 downto 0)) return r_FMOH is
variable v_FMOH : r_FMOH;
begin
v_FMOH.OP := t_operations'val(to_integer(unsigned(r_register(t_operations'pos(t_operations'high) downto 0))));
v_FMOH.x := r_register(2);
v_FMOH.OPP := r_register(3);
v_FMOH.y := r_register(15 downto 4);
v_FMOH.PG := r_register(23 downto 16);
v_FMOH.SCT := r_register(29 downto 24);
v_FMOH.z := r_register(31 downto 30);
return v_FMOH;
end f_FMOH;
end m25p32_pkg;
......@@ -19,7 +19,9 @@
--
----------------------------------------------------------------------------------
library IEEE;
library work;
use IEEE.STD_LOGIC_1164.ALL;
use work.m25p32_pkg.ALL;
entity m25p32_regs is
port (
......@@ -32,93 +34,92 @@ entity m25p32_regs is
wb_sel_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_data_i : in STD_LOGIC_VECTOR (31 downto 0);
wb_data_o : out STD_LOGIC_VECTOR (31 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR (31 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_ack_o : out STD_LOGIC;
wb_rty_o : out STD_LOGIC;
wb_err_o : out STD_LOGIC;
CTR0_i : in STD_LOGIC_VECTOR (31 downto 0);
CTR1_i : in STD_LOGIC_VECTOR (31 downto 0);
STATUS_o : out STD_LOGIC_VECTOR (31 downto 0)
CTR0_i : in STD_LOGIC_VECTOR (7 downto 0);
FMOH_o : out STD_LOGIC_VECTOR (31 downto 0)
);
end m25p32_regs;
architecture Behavioral of m25p32_regs is
constant CTR0_addr : STD_LOGIC_VECTOR (3 downto 0) := X"0";
constant CTR1_addr : STD_LOGIC_VECTOR (3 downto 0) := X"1";
constant STATUS_addr : STD_LOGIC_VECTOR (3 downto 0) := X"2";
signal s_CTR0 : r_CTR0;
signal s_FMOH : r_FMOH;
signal s_CTR0 : STD_LOGIC_VECTOR (31 downto 0);
signal s_CTR1 : STD_LOGIC_VECTOR (31 downto 0);
signal s_STATUS : STD_LOGIC_VECTOR (31 downto 0);
signal s_wb_ack_o : STD_LOGIC;
signal s_wb_rty_o : STD_LOGIC;
signal s_wb_err_o : STD_LOGIC;
signal s_wb_ack_o : STD_LOGIC;
signal s_wb_rty_o : STD_LOGIC;
signal s_wb_err_o : STD_LOGIC;
begin
wbslave_proc: process (wb_clk)
wb_ack_o <= s_wb_ack_o;
wb_rty_o <= s_wb_rty_o;
wb_err_o <= s_wb_err_o;
p_wbslave: process (wb_clk)
begin
if rising_edge(wb_clk) then
if wb_rst_i = '1' then
s_CTR0 <= (others => '0');
s_CTR1 <= (others => '0');
s_STATUS <= (others => '0');
elsif (wb_stb_i = '1' and wb_cyc_i = '1') then
if (s_wb_ack_o or s_wb_rty_o or s_wb_err_o) = '1' then
s_wb_ack_o <= '0';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
s_CTR0 <= c_CTR0_default;
s_FMOH <= c_FMOH_default;
s_wb_ack_o <= '0';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
else
if s_CTR0.OPF = '1' then
s_FMOH.OPP <= '0';
else
end if;
if (wb_stb_i = '1' and wb_cyc_i = '1') then
if (s_wb_ack_o or s_wb_rty_o or s_wb_err_o) = '1' then
s_wb_ack_o <= '0';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
else
case wb_we_i is
when '1' =>
case wb_addr_i(3 downto 0) is
when c_FMOH_addr =>
if s_FMOH.OPP = '0' then
s_FMOH <= f_FMOH(wb_data_i);
s_wb_ack_o <= '1';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
else
s_wb_ack_o <= '0';
s_wb_rty_o <= '0';
s_wb_err_o <= '1';
end if;
when others =>
s_wb_ack_o <= '0';
s_wb_rty_o <= '0';
s_wb_err_o <= '1';
end case;
when others =>
case wb_addr_i is
when c_CTR0_addr =>
wb_data_o(7 downto 0) <= f_STD_LOGIC_VECTOR(s_CTR0);
wb_data_o(31 downto 8) <= (others => '0');
s_wb_ack_o <= '1';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
when c_FMOH_addr =>
wb_data_o <= f_STD_LOGIC_VECTOR(s_FMOH);
s_wb_ack_o <= '1';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
when others =>
s_wb_ack_o <= '0';
s_wb_rty_o <= '0';
s_wb_err_o <= '1';
end case;
end case;
end if;
else
case wb_we_i is
when '1' =>
case wb_addr_i is
when CTR0_addr =>
s_CTR0 <= wb_data_i;
s_wb_ack_o <= '1';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
when CTR1_addr =>
s_CTR1 <= wb_data_i;
s_wb_ack_o <= '1';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
when STATUS_addr =>
s_STATUS <= wb_data_i;
s_wb_ack_o <= '1';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
when others =>
s_wb_ack_o <= '0';
s_wb_rty_o <= '0';
s_wb_err_o <= '1';
end case;
when others =>
case wb_addr_i is
when CTR0_addr =>
wb_data_o <= s_CTR0;
s_wb_ack_o <= '1';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
when CTR1_addr =>
wb_data_o <= s_CTR1;
s_wb_ack_o <= '1';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
when STATUS_addr =>
wb_data_o <= s_STATUS;
s_wb_ack_o <= '1';
s_wb_rty_o <= '0';
s_wb_err_o <= '0';
when others =>
s_wb_ack_o <= '0';
s_wb_rty_o <= '0';
s_wb_err_o <= '1';
end case;
end case;
end if;
end if;
else
......@@ -126,4 +127,3 @@ begin
end process;
end Behavioral;
......@@ -18,19 +18,22 @@
--
----------------------------------------------------------------------------------
library IEEE;
library work;
use IEEE.STD_LOGIC_1164.ALL;
use work.m25p32_pkg.ALL;
entity m25p32_top is
port (
wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
wb_we_i : in STD_LOGIC;
wb_stb_i : in STD_LOGIC;
wb_cyc_i : in STD_LOGIC;
wb_sel_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_data_i : in STD_LOGIC_VECTOR(31 downto 0);
wb_data_i : out STD_LOGIC_VECTOR(31 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR(31 downto 0);
wb_data_o : out STD_LOGIC_VECTOR(31 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR(3 downto 0);
wb_ack_o : out STD_LOGIC;
wb_rty_o : out STD_LOGIC;
wb_err_o : out STD_LOGIC;
......@@ -38,14 +41,85 @@ entity m25p32_top is
prom_mosi_o : out STD_LOGIC;
prom_cclk_o : out STD_LOGIC;
prom_cs0_b_n_o : out STD_LOGIC;
prom_din_o : out STD_LOGIC
);
prom_din_i : in STD_LOGIC
);
end m25p32_top;
architecture Behavioral of m25p32_top is
signal s_CTR0 : STD_LOGIC_VECTOR(7 downto 0);
signal s_FMOH : STD_LOGIC_VECTOR(31 downto 0);
component m25p32_core is
port (
wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
mosi_o : out STD_LOGIC;
miso_i : in STD_LOGIC;
sclk_o : out STD_LOGIC;
ss_n_o : out STD_LOGIC;
CTR0_o : out STD_LOGIC_VECTOR (7 downto 0);
FMOH_i : in STD_LOGIC_VECTOR (31 downto 0)
);
end component;
component m25p32_regs is
port (
wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
wb_we_i : in STD_LOGIC;
wb_stb_i : in STD_LOGIC;
wb_cyc_i : in STD_LOGIC;
wb_sel_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_data_i : in STD_LOGIC_VECTOR (31 downto 0);
wb_data_o : out STD_LOGIC_VECTOR (31 downto 0);
wb_addr_i : in STD_LOGIC_VECTOR (3 downto 0);
wb_ack_o : out STD_LOGIC;
wb_rty_o : out STD_LOGIC;
wb_err_o : out STD_LOGIC;
CTR0_i : in STD_LOGIC_VECTOR (7 downto 0);
FMOH_o : out STD_LOGIC_VECTOR (31 downto 0)
);
end component;
begin
inst_m25p32_core: m25p32_core
port map (
wb_rst_i => wb_rst_i,
wb_clk => wb_clk,
end Behavioral;
mosi_o => prom_mosi_o,
miso_i => prom_din_i,
sclk_o => prom_cclk_o,
ss_n_o => prom_cs0_b_n_o,
CTR0_o => s_CTR0,
FMOH_i => s_FMOH
);
inst_m25p32_regs: m25p32_regs
port map (
wb_rst_i => wb_rst_i,
wb_clk => wb_clk,
wb_we_i => wb_we_i,
wb_stb_i => wb_stb_i,
wb_cyc_i => wb_cyc_i,
wb_sel_i => wb_sel_i,
wb_data_i => wb_data_i,
wb_data_o => wb_data_o,
wb_addr_i => wb_addr_i,
wb_ack_o => wb_ack_o,
wb_rty_o => wb_rty_o,
wb_err_o => wb_err_o,
CTR0_i => s_CTR0,
FMOH_o => s_FMOH
);
end Behavioral;
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 17:34:27 06/14/2012
-- Design Name:
-- Module Name: spi_master_core - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
library work;
use IEEE.STD_LOGIC_1164.ALL;
use work.spi_master_pkg.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
entity spi_master_core is
generic(
g_inst_width := c_inst_width;
g_addr_width := c_addr_width;
g_data_width := c_data_width);
port(
rst_i : in STD_LOGIC;
clk : in STD_LOGIC
inst_i : in STD_LOGIC_VECTOR (8*g_inst_width - 1 downto 0);
addr_i : in STD_LOGIC_VECTOR (8*g_addr_width - 1 downto 0);
data_i : in STD_LOGIC_VECTOR (8*g_data_width - 1 downto 0);
push_inst_i : in STD_LOGIC;
push_addr_i : in STD_LOGIC;
push_data_i : in STD_LOGIC;
data_i : in STD_LOGIC_VECTOR (8*g_data_width - 1 downto 0);
SPI0_i : in STD_LOGIC_VECTOR (31 downto 0)
);
end spi_master_core;
architecture Behavioral of spi_master_core is
begin
end Behavioral;
--
-- Package File Template
--
-- Purpose: This package defines supplemental types, subtypes,
-- constants, and functions
--
-- To use any of the example code shown below, uncomment the lines and modify as necessary
--
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package spi_master_pkg is
----------------------------------------
-- SPI0 register
----------------------------------------
-- 32 bits
-- Wishbone access: 32 bits
----------------------------------------
-- BIT NAME DESCRIPTION
-- 0 SEND SEND
-- 1 PDATA Push DATA bytes into internal SPI core memory
-- 2 PADDR Push ADDRess bytes into internal SPI core memory
-- 3 PINST Push INSTruction bytes into internal SPI core memory
-- 7-4 x Reserved
-- 15-8 BDATA Bytes of DATA to be sent
-- 23-16 BADDR Bytes of ADDRess to be sent
-- 31-24 BINST Bytes of INSTruction to be sent
----------------------------------------
type r_SPI0 is
record
SEND : STD_LOGIC;
PDATA : STD_LOGIC;
PADDR : STD_LOGIC;
PINST : STD_LOGIC;
x : STD_LOGIC_VECTOR (7 downto 4);
BDATA : UNSIGNED (15 downto 8);
BADDR : UNSIGNED (23 downto 16);
BINST : UNSIGNED (31 downto 24);
end record;
constant c_inst_width : NATURAL := 1;
constant c_addr_width : NATURAL := 3;
constant c_data_width : NATURAL := 256;
constant c_SPI0_addr : STD_LOGIC_VECTOR (3 downto 0) := X"0";
-- Declare functions and procedure
--
-- function <function_name> (signal <signal_name> : in <type_declaration>) return <type_declaration>;
-- procedure <procedure_name> (<type_declaration> <constant_name> : in <type_declaration>);
--
end spi_master_pkg;
package body spi_master_pkg is
---- Example 1
-- function <function_name> (signal <signal_name> : in <type_declaration> ) return <type_declaration> is
-- variable <variable_name> : <type_declaration>;
-- begin
-- <variable_name> := <signal_name> xor <signal_name>;
-- return <variable_name>;
-- end <function_name>;
---- Example 2
-- function <function_name> (signal <signal_name> : in <type_declaration>;
-- signal <signal_name> : in <type_declaration> ) return <type_declaration> is
-- begin
-- if (<signal_name> = '1') then
-- return <signal_name>;
-- else
-- return 'Z';
-- end if;
-- end <function_name>;
---- Procedure Example
-- procedure <procedure_name> (<type_declaration> <constant_name> : in <type_declaration>) is
--
-- begin
--
-- end <procedure_name>;
end spi_master_pkg;
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 17:34:08 06/14/2012
-- Design Name:
-- Module Name: spi_master_regs - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity spi_master_regs is
end spi_master_regs;
architecture Behavioral of spi_master_regs is
begin
end Behavioral;
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 17:33:55 06/14/2012
-- Design Name:
-- Module Name: spi_master_top - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity spi_master_top is
end spi_master_top;
architecture Behavioral of spi_master_top is
begin
end Behavioral;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment