Commit 55fafcd6 authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

Bicolor LED controller tested & working

parent 6bc77271
modules = {
"local" : [ "top" ]
}
files = [
"conv_regs.vhd",
"conv_pulse_gen.vhd",
"conv_man_trig.vhd",
"conv_ring_buf.vhd",
"conv_pulse_timetag.vhd",
"conv_reset_gen.vhd"
];
conv_regs.wb
============
If you change the FIFO width in the top-level conv_ttl_blo.vhd, you need to
also change the width of the USEDW field.
conv_regs.vhd
=============
You need to make some changes to this file after EVERY RUN of wbgen2:
1. Add the following output port declaration after the reg_tbmr_wrtag_i port:
-- Tag buffer read request, asserted when reading from TBMR
reg_tb_rd_req_p_o : out std_logic;
2. Assign the port FOUR TIMES in the register bank process:
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
-- [...]
reg_tb_rd_req_p_o <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
-- [...]
reg_tb_rd_req_p_o <= '0';
ack_in_progress <= '0';
else
-- [...]
reg_tb_rd_req_p_o <= '0';
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(3 downto 0) is
[...]
when "1011" =>
if (wb_we_i = '1') then
end if;
reg_tb_rd_req_p_o <= '1';
rddata_reg(5 downto 0) <= reg_tbmr_chan_i;
rddata_reg(31) <= reg_tbmr_wrtag_i;
[...]
--==============================================================================
-- CERN (BE-CO-HT)
-- Pulse trigger for pulse converter boards
--==============================================================================
--
-- author: Theodor Stana (t.stana@cern.ch)
--
-- date of creation: 2014-01-28
--
-- version: 1.0
--
-- description:
-- This module generates a pulse for the conv_pulse_gen module for manually
-- triggering a debug pulse on a channel output. It works in conjunction
-- with the converter board registers component (conv_regs), from where it
-- obtains the value of the MPT (manual pulse trigger) field in the control
-- register.
--
-- To manually trigger a pulse, a magic sequence of numbers (0xde, 0xad, 0xbe,
-- 0xef) should first be sent to the MPT field, followed by the channel number
-- to send the pulse on. When the channel number is sent, a single pulse is
-- generated by the conv_pulse_gen component at the output.
--
-- The conv_man_trig module checks to see whether the proper magic sequence
-- is written the the MPT field using a simple FSM. The FSM advances when
-- the MPT field is written, if the MPT field corresponds to the proper byte
-- in the magic sequence. If at any time during the magic sequence the value
-- of the MPT field does not correspond to the expected value, the FSM returns
-- to IDLE.
--
-- After the magic sequence is received, the FSM waits for the channel number
-- to be written to the MPT. If a valid channel number is input, a pulse is
-- generated on this channel. The check of whether a valid number is input is
-- based on the g_nr_ttl_chan generic. Should an invalid channel number be
-- input, no error is reported and no pulse is generated.
--
-- The output trigger pulse is extended within the last state of the FSM, to
-- account for when the glitch filter of the conv_pulse_gen component is on.
-- To extend the pulse by an appropriate number of clock cycles, the length
-- of the conv_pulse_gen glitch filter should be input via the g_gf_len.
--
-- dependencies:
-- genram_pkg : git://ohwr.org/hdl-core-lib/general-cores.git
--
--==============================================================================
-- 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:
-- 2014-01-28 Theodor Stana File created
--==============================================================================
-- TODO: -
--==============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
entity conv_man_trig is
generic
(
-- Number of conversion channels
g_nr_chan : positive := 6;
-- Length of pulse generator glitch filter, needed to generate a long
-- enough pulse
g_gf_len : positive := 1
);
port
(
-- Clock, active-low inputs
clk_i : in std_logic;
rst_n_i : in std_logic;
-- Control inputs from conv_regs
reg_ld_i : in std_logic;
reg_i : in std_logic_vector(7 downto 0);
-- One-clock pulse output
trig_o : out std_logic_vector(g_nr_chan downto 1)
);
end entity conv_man_trig;
architecture behav of conv_man_trig is
--============================================================================
-- Type declarations
--============================================================================
-- Type for the "password" array
type t_pass_arr is array(integer range <>) of std_logic_vector(7 downto 0);
-- FSM type
type t_state is
(
IDLE,
PASS1,
PASS2,
PASS3,
GET_CHAN,
GEN
);
--============================================================================
-- Constant declarations
--============================================================================
constant c_pass_arr : t_pass_arr(0 to 3) := (x"de", x"ad", x"be", x"ef");
--============================================================================
-- Function and procedures declaration
--============================================================================
procedure f_change_state (
signal ld : in std_logic;
signal pass : in std_logic_vector(7 downto 0);
constant idx : in integer;
signal state : out t_state;
constant nstate : in t_state
) is
begin
if (ld = '1') then
if (pass = c_pass_arr(idx)) then
state <= nstate;
else
state <= IDLE;
end if;
end if;
end procedure f_change_state;
--============================================================================
-- Signal declarations
--============================================================================
-- Signal for the current state of the FSM
signal state : t_state;
-- Counter to extend the pulse to the needed number of channels
signal cnt : unsigned(f_log2_size(g_gf_len)-1 downto 0);
--==============================================================================
-- architecture begin
--==============================================================================
begin
--============================================================================
-- FSM logic
--============================================================================
p_fsm : process (clk_i)
begin
if rising_edge(clk_i) then
if (rst_n_i = '0') then
state <= IDLE;
cnt <= (others => '0');
trig_o <= (others => '0');
else
case state is
when IDLE =>
trig_o <= (others => '0');
f_change_state(reg_ld_i, reg_i, 0, state, PASS1);
when PASS1 =>
f_change_state(reg_ld_i, reg_i, 1, state, PASS2);
when PASS2 =>
f_change_state(reg_ld_i, reg_i, 2, state, PASS3);
when PASS3 =>
f_change_state(reg_ld_i, reg_i, 3, state, GET_CHAN);
when GET_CHAN =>
if (reg_ld_i = '1') then
for i in 1 to g_nr_chan loop
if (i = to_integer(unsigned(reg_i))) then
trig_o(i) <= '1';
end if;
end loop;
cnt <= (others => '0');
state <= GEN;
end if;
when GEN =>
cnt <= cnt + 1;
if (cnt = g_gf_len-1) then
state <= IDLE;
end if;
when others =>
state <= IDLE;
end case;
end if;
end if;
end process p_fsm;
end architecture behav;
--==============================================================================
-- architecture end
--==============================================================================
This diff is collapsed.
--==============================================================================
-- CERN (BE-CO-HT)
-- Pulse time-tagging core
--==============================================================================
--
-- author: Theodor Stana (t.stana@cern.ch)
--
-- date of creation: 2014-02-04
--
-- version: 1.0
--
-- description:
-- This module contains the internal timetag counter, counting on an 8 ns
-- clock. When a pulse arrives on the input, it triggers the writing of a
-- timetag to a FIFO memory external to the module.
--
-- dependencies:
-- gencores_pkg : git://ohwr.org/hdl-core-lib/general-cores.git
--
--==============================================================================
-- 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:
-- 2014-02-04 Theodor Stana File created
--==============================================================================
-- TODO: -
--==============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gencores_pkg.all;
entity conv_pulse_timetag is
generic
(
-- Frequency in Hz of the clk_i signal
g_clk_rate : positive := 125000000;
-- Number of repetition channels
g_nr_chan : positive := 6
);
port
(
-- Clock and active-low reset
clk_i : in std_logic;
rst_n_i : in std_logic;
-- Asynchronous pulse input
pulse_a_i : in std_logic_vector(g_nr_chan downto 1);
-- Time inputs from White Rabbit
wr_tm_cycles_i : in std_logic_vector(27 downto 0);
wr_tm_tai_i : in std_logic_vector(39 downto 0);
wr_tm_valid_i : in std_logic;
-- Timing inputs from Wishbone-mapped registers
wb_tm_tai_l_i : in std_logic_vector(31 downto 0);
wb_tm_tai_l_ld_i : in std_logic;
wb_tm_tai_h_i : in std_logic_vector( 7 downto 0);
wb_tm_tai_h_ld_i : in std_logic;
-- Timing outputs
tm_cycles_o : out std_logic_vector(27 downto 0);
tm_tai_o : out std_logic_vector(39 downto 0);
tm_wrpres_o : out std_logic;
chan_o : out std_logic_vector(g_nr_chan downto 1);
-- Ring buffer I/O
buf_wr_req_p_o : out std_logic
);
end entity conv_pulse_timetag;
architecture behav of conv_pulse_timetag is
--============================================================================
-- Signal declarations
--============================================================================
signal cycles_cnt : unsigned(27 downto 0);
signal cycles_tick : std_logic;
signal tai_cnt : unsigned(39 downto 0);
signal tai_l_ld : std_logic;
signal tai_h_ld : std_logic;
signal pulse_redge_p : std_logic_vector(g_nr_chan downto 1);
signal pulse_redge_p_d0 : std_logic_vector(g_nr_chan downto 1);
--==============================================================================
-- architecture begin
--==============================================================================
begin
--============================================================================
-- Time counter logic
--============================================================================
-- The Wishbone bus may be in a different clock domain than the time tag core,
-- so first we need to synchronize the LD signals
cmp_sync_l_ld : gc_sync_ffs
port map
(
clk_i => clk_i,
rst_n_i => rst_n_i,
data_i => wb_tm_tai_l_ld_i,
ppulse_o => tai_l_ld
);
cmp_sync_h_ld : gc_sync_ffs
port map
(
clk_i => clk_i,
rst_n_i => rst_n_i,
data_i => wb_tm_tai_h_ld_i,
ppulse_o => tai_h_ld
);
-- Generate the counters
p_cycle_cnt : process (clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
cycles_cnt <= (others => '0');
cycles_tick <= '0';
else
cycles_cnt <= cycles_cnt + 1;
cycles_tick <= '0';
-- TAI counter loaded from Wishbone
if tai_l_ld = '1' or tai_h_ld = '1' then
cycles_cnt <= (others => '0');
-- Tick and reset on second
elsif cycles_cnt = g_clk_rate-1 then
cycles_cnt <= (others => '0');
cycles_tick <= '1';
end if;
end if;
end if;
end process p_cycle_cnt;
p_tai_cnt : process (clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
tai_cnt <= (others => '0');
-- Load from Wishbone
elsif tai_l_ld = '1' then
tai_cnt(31 downto 0) <= unsigned(wb_tm_tai_l_i);
elsif tai_h_ld = '1' then
tai_cnt(39 downto 32) <= unsigned(wb_tm_tai_h_i);
-- Increment on cycles second tick
elsif cycles_tick = '1' then
tai_cnt <= tai_cnt + 1;
end if;
end if;
end process p_tai_cnt;
--============================================================================
-- Control logic for the FIFO
--============================================================================
-- First, synchronize the pulse inputs in the clk_i domain
gen_sync_chains : for i in 1 to g_nr_chan generate
cmp_pulse_sync : gc_sync_ffs
generic map
(
g_sync_edge => "positive"
)
port map
(
clk_i => clk_i,
rst_n_i => '1',
data_i => pulse_a_i(i),
ppulse_o => pulse_redge_p(i)
);
end generate gen_sync_chains;
-- Set the control signals to the ring buffer on the rising edge of any
-- pulse channel
p_buf_ctrl : process (clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
buf_wr_req_p_o <= '0';
else
buf_wr_req_p_o <= '0';
if not (pulse_redge_p = (pulse_redge_p'range => '0')) then
buf_wr_req_p_o <= '1';
end if;
end if;
end if;
end process p_buf_ctrl;
-- And delay the pulse rising edge for sampling (this is due to the delayed
-- setting of the write signal to the FIFO)
p_dly_pulse : process (clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pulse_redge_p_d0 <= (others => '0');
else
pulse_redge_p_d0 <= pulse_redge_p;
end if;
end if;
end process p_dly_pulse;
--============================================================================
-- Output logic
--============================================================================
-- Multiplex the timing outputs between WR and internal counters
tm_cycles_o <= wr_tm_cycles_i when wr_tm_valid_i = '1' else
std_logic_vector(cycles_cnt);
tm_tai_o <= wr_tm_tai_i when wr_tm_valid_i = '1' else
std_logic_vector(tai_cnt);
tm_wrpres_o <= wr_tm_valid_i;
chan_o <= pulse_redge_p_d0;
end architecture behav;
--==============================================================================
-- architecture end
--==============================================================================
This diff is collapsed.
This diff is collapsed.
--==============================================================================
-- CERN (BE-CO-HT)
-- Reset generator for CONV-TTL-* boards
--==============================================================================
--
-- author: Theodor Stana (t.stana@cern.ch)
--
-- date of creation: 2013-03-05
--
-- version: 1.0
--
-- description:
-- This module generates a controllable-width reset pulse. The width of the
-- reset pulse is set via the g_reset_time pulse; an internal counter counts
-- up to this value and de-asserts the active-low reset line when the value
-- has been reached. At the same time, the module is de-activated.
--
-- By default, a 20 MHz clock (50 ns period) is assumed, resulting in a 100ms
-- reset width.
--
-- dependencies:
-- none
--
--==============================================================================
-- 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-03-05 Theodor Stana File created
--==============================================================================
-- TODO: -
--==============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity conv_reset_gen is
generic
(
-- Reset time in number of clk_i cycles
g_reset_time : positive := 2_000_000
);
port
(
clk_i : in std_logic;
rst_i : in std_logic;
rst_n_o : out std_logic
);
end entity conv_reset_gen;
architecture behav of conv_reset_gen is
--============================================================================
-- Function and procedure declarations
--============================================================================
function f_log2_size (A : natural) return natural is
begin
for I in 1 to 64 loop -- Works for up to 64 bits
if (2**I >= A) then
return(I);
end if;
end loop;
return(63);
end function f_log2_size;
--============================================================================
-- Signal declarations
--============================================================================
signal cnt : unsigned(f_log2_size(g_reset_time)-1 downto 0) := (others => '0');
signal cnt_en : std_logic := '1';
--==============================================================================
-- architecture begin
--==============================================================================
begin
--============================================================================
-- Reset generation logic
--============================================================================
p_rst_gen: process(clk_i)
begin
if rising_edge(clk_i) then
if (rst_i = '1') then
cnt_en <= '1';
cnt <= (others => '0');
elsif (cnt_en = '1') then
rst_n_o <= '0';
cnt <= cnt + 1;
if (cnt = g_reset_time-1) then
rst_n_o <= '1';
cnt_en <= '0';
end if;
end if;
end if;
end process p_rst_gen;
end architecture behav;
--==============================================================================
-- architecture end
--==============================================================================
--==============================================================================
-- CERN (BE-CO-HT)
-- Ring buffer for converter board designs
--==============================================================================
--
-- author: Theodor Stana (t.stana@cern.ch)
--
-- date of creation: 2014-03-19
--
-- version: 1.0
--
-- description:
-- Ring buffer memory with configurable (at synthesis time) data width and
-- size. Although created for the converter board design, it can be used in
-- any desing.
--
-- dependencies:
-- genram_pkg : git://ohwr.org/hdl-core-lib/general-cores.git
--
--==============================================================================
-- 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:
-- 2014-03-19 Theodor Stana Created file and copied content from
-- fd_ring_buffer.
--==============================================================================
-- TODO: -
--==============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
entity conv_ring_buf is
generic
(
-- Buffer data input and output width
g_data_width : positive;
-- Buffer size in number of samples
g_size : positive
);
port
(
-- Clocks and reset
clk_rd_i : in std_logic;
clk_wr_i : in std_logic;
rst_n_a_i : in std_logic;
-- Buffer inputs
buf_dat_i : in std_logic_vector(g_data_width-1 downto 0);
buf_rd_req_i : in std_logic;
buf_wr_req_i : in std_logic;
buf_clr_i : in std_logic;
-- Buffer outputs
buf_dat_o : out std_logic_vector(g_data_width-1 downto 0);
buf_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
buf_full_o : out std_logic;
buf_empty_o : out std_logic
);
end entity conv_ring_buf;
architecture behav of conv_ring_buf is
--============================================================================
-- Type declarations
--============================================================================
--============================================================================
-- Constant declarations
--============================================================================
constant c_fifo_size : positive := 8;
--============================================================================
-- Signal declarations
--============================================================================
-- FIFO signals
signal fifo_full : std_logic;
signal fifo_empty : std_logic;
signal fifo_read : std_logic;
signal fifo_read_d0 : std_logic;
signal fifo_write : std_logic;
signal fifo_in : std_logic_vector(g_data_width-1 downto 0);
signal fifo_out : std_logic_vector(g_data_width-1 downto 0);
-- Buffer signals
signal buf_write : std_logic;
signal buf_read : std_logic;
signal buf_wr_ptr : unsigned(f_log2_size(g_size)-1 downto 0);
signal buf_rd_ptr : unsigned(f_log2_size(g_size)-1 downto 0);
signal buf_wr_data : std_logic_vector(g_data_width-1 downto 0);
signal buf_rd_data : std_logic_vector(g_data_width-1 downto 0);
signal buf_count : unsigned(f_log2_size(g_size)-1 downto 0);
signal buf_empty : std_logic;
signal buf_full : std_logic;
signal buf_overflow : std_logic;
--==============================================================================
-- architecture begin
--==============================================================================
begin
--============================================================================
-- Buffer FIFO and RAM
--============================================================================
-- Assign FIFO input and control
fifo_in <= buf_dat_i;
fifo_write <= not fifo_full and buf_wr_req_i;
fifo_read <= not fifo_empty;
-- Instantiate FIFO to synchronize data inputs from read clock to write clock
cmp_clk_adjust_fifo : generic_async_fifo
generic map
(
g_data_width => fifo_in'length,
g_size => c_fifo_size
)
port map (
rst_n_i => rst_n_a_i,
clk_wr_i => clk_wr_i,
d_i => fifo_in,
we_i => fifo_write,
wr_full_o => fifo_full,
clk_rd_i => clk_rd_i,
q_o => fifo_out,
rd_i => fifo_read,
rd_empty_o => fifo_empty);
-- Instantiate the actual buffer RAM
-- The buffer gets fed with data from the FIFO
buf_wr_data <= fifo_out;
cmp_buf_ram : generic_dpram
generic map (
g_data_width => g_data_width,
g_size => g_size,
g_dual_clock => false)
port map (
rst_n_i => rst_n_a_i,
clka_i => clk_rd_i,
bwea_i => (others => '1'),
wea_i => buf_write,
aa_i => std_logic_vector(buf_wr_ptr),
da_i => buf_wr_data,
qa_o => open,
clkb_i => clk_rd_i,
bweb_i => (others => '0'),
web_i => '0',
ab_i => std_logic_vector(buf_rd_ptr),
db_i => (others => '0'),
qb_o => buf_rd_data);
--============================================================================
-- Buffer control
--============================================================================
-- Assign buffer control signals
buf_write <= fifo_read_d0;
buf_read <= '1' when ((buf_rd_req_i = '1') and (buf_empty = '0')) or
(buf_overflow = '1')
else '0';
buf_overflow <= '1' when (buf_write = '1') and (buf_full = '1') else '0';
-- Buffer control process
p_buffer_control : process(clk_rd_i)
begin
if rising_edge(clk_rd_i) then
if (rst_n_a_i = '0') or (buf_clr_i = '1') then
buf_rd_ptr <= (others => '0');
buf_wr_ptr <= (others => '0');
buf_count <= (others => '0');
buf_full <= '0';
buf_empty <= '1';
fifo_read_d0 <= '0';
else
fifo_read_d0 <= fifo_read;
-- Read and write signals
if(buf_write = '1') then
buf_wr_ptr <= buf_wr_ptr + 1;
end if;
if(buf_read = '1') then
buf_rd_ptr <= buf_rd_ptr + 1;
end if;
-- Buffer count and full/empty control
if (buf_write = '1') and (buf_read = '0') and (buf_full = '0') then
buf_count <= buf_count + 1;
buf_empty <= '0';
if (buf_count = (buf_count'range => '1')) then
buf_full <= '1';
end if;
end if;
if (buf_write = '0') and (buf_read = '1') and (buf_empty = '0') then
buf_count <= buf_count - 1;
buf_full <= '0';
if (buf_count = 1) then
buf_empty <= '1';
end if;
end if;
end if;
end if;
end process;
--============================================================================
-- Output signals
--============================================================================
buf_full_o <= buf_full;
buf_empty_o <= buf_empty;
buf_count_o <= std_logic_vector(buf_count);
buf_dat_o <= buf_rd_data;
end architecture behav;
--==============================================================================
-- architecture end
--==============================================================================
files = [
"conv_common_gw.vhd"
]
modules = {
"local" : [
"../ip_cores/general-cores",
"../modules"
]
}
--==============================================================================
-- CERN (BE-CO-HT)
-- Converter board common gateware top-level file
--==============================================================================
--
-- author: Theodor Stana (t.stana@cern.ch)
--
-- date of creation: 2014-07-24
--
-- version: 1.0
--
-- description:
-- This module is to be instantiated in all pulse converter board designs,
-- for example the CONV-TTL-BLO or CONV-TTL-RS485. It contains a set of
-- modules common to all these boards, that are configurable via generics to
-- accommodate for the application of each board.
--
-- dependencies:
-- general-cores repository [1]
--
-- references:
-- [1] Platform-independent core collection webpage on OHWR,
-- http://www.ohwr.org/projects/general-cores/repository
-- [2] ELMA, Access to board data using SNMP and I2C
-- http://www.ohwr.org/documents/227
--
--==============================================================================
-- 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:
-- 2014-07-24 Theodor Stana File created
--==============================================================================
-- TODO: -
--==============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library unisim;
use unisim.vcomponents.all;
use work.gencores_pkg.all;
use work.wishbone_pkg.all;
use work.genram_pkg.all;
entity conv_common_gw is
generic
(
-- Number of repeater channels
g_nr_chans : integer := 6;
-- Bicolor LED controller signals
g_bicolor_led_columns : integer := 6;
g_bicolor_led_lines : integer := 2
);
port
(
-- Clocks
clk_20_i : in std_logic;
clk_125_p_i : in std_logic;
clk_125_n_i : in std_logic;
-- Reset output signal, synchronous to 20 MHz clock
rst_n_o : out std_logic;
-- Bicolor LED signals
bicolor_led_state_i : in std_logic_vector(2*g_bicolor_led_columns*g_bicolor_led_lines-1 downto 0);
bicolor_led_col_o : out std_logic_vector(g_bicolor_led_columns-1 downto 0);
bicolor_led_line_o : out std_logic_vector(g_bicolor_led_lines-1 downto 0);
bicolor_led_line_oen_o : out std_logic_vector(g_bicolor_led_lines-1 downto 0)
);
end entity conv_common_gw;
architecture arch of conv_common_gw is
--============================================================================
-- Type declarations
--============================================================================
--============================================================================
-- Constant declarations
--============================================================================
-- Number of Wishbone masters and slaves, for wb_crossbar
constant c_nr_masters : natural := 1;
constant c_nr_slaves : natural := 3;
-- slave order definitions
constant c_slv_conv_regs : natural := 0;
constant c_slv_multiboot : natural := 1;
constant c_slv_onewire_mst : natural := 2;
-- base address definitions
constant c_addr_conv_regs : t_wishbone_address := x"00000000";
constant c_addr_multiboot : t_wishbone_address := x"00000040";
constant c_addr_onewire_mst : t_wishbone_address := x"00000080";
-- address mask definitions
constant c_mask_conv_regs : t_wishbone_address := x"00000fc0";
constant c_mask_multiboot : t_wishbone_address := x"00000fc0";
constant c_mask_onewire_mst : t_wishbone_address := x"00000fe0";
-- addresses constant for Wishbone crossbar
constant c_addresses : t_wishbone_address_array(c_nr_slaves-1 downto 0)
:= (
c_slv_conv_regs => c_addr_conv_regs,
c_slv_multiboot => c_addr_multiboot,
c_slv_onewire_mst => c_addr_onewire_mst
);
-- masks constant for Wishbone crossbar
constant c_masks : t_wishbone_address_array(c_nr_slaves-1 downto 0)
:= (
c_slv_conv_regs => c_mask_conv_regs,
c_slv_multiboot => c_mask_multiboot,
c_slv_onewire_mst => c_mask_onewire_mst
);
--============================================================================
-- Component declarations
--============================================================================
------------------------------------------------------------------------------
-- Fixed-width reset generator
------------------------------------------------------------------------------
component conv_reset_gen is
generic
(
-- Reset time in number of clk_i cycles
g_reset_time : positive := 2_000_000
);
port
(
clk_i : in std_logic;
rst_i : in std_logic;
rst_n_o : out std_logic
);
end component conv_reset_gen;
--============================================================================
-- Signal declarations
--============================================================================
-- Per-domain clock and reset signals
signal clk_125 : std_logic;
signal rst_125_n : std_logic;
signal rst_20_n : std_logic;
--==============================================================================
-- architecture begin
--==============================================================================
begin
--============================================================================
-- Internal and external reset generation
--============================================================================
-- Configure reset generator for 100ms power-on reset
cmp_reset_gen : conv_reset_gen
generic map
(
-- Reset time: 50ns * 2 * (10**6) = 100 ms
g_reset_time => 2*(10**6)
)
port map
(
clk_i => clk_20_i,
rst_i => '0',
rst_n_o => rst_20_n
);
-- Output reset signal is synchronous to the 20 MHz clock
rst_n_o <= rst_20_n;
--============================================================================
-- Bicolor LED matrix logic
--============================================================================
-- connect column, line & state signals outside
cmp_bicolor_led_ctrl : gc_bicolor_led_ctrl
generic map
(
g_NB_COLUMN => g_bicolor_led_columns,
g_NB_LINE => g_bicolor_led_lines,
g_clk_freq => 20000000,
g_refresh_rate => 250
)
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
led_intensity_i => "1111111",
led_state_i => bicolor_led_state_i,
column_o => bicolor_led_col_o,
line_o => bicolor_led_line_o,
line_oen_o => bicolor_led_line_oen_o
);
end architecture arch;
--==============================================================================
-- architecture end
--==============================================================================
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