pax_global_header 0000666 0000000 0000000 00000000064 11632347016 0014515 g ustar 00root root 0000000 0000000 52 comment=150af6c1d7afed4e2b9c413bc4f66eb3702c897b
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/ 0000775 0000000 0000000 00000000000 11632347016 0020434 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/README 0000664 0000000 0000000 00000000540 11632347016 0021313 0 ustar 00root root 0000000 0000000 Time to Digital Converter core for Spartan-6 FPGAs
==================================================
Directory organization:
core/ VHDL sources of the TDC core.
demo/ Demonstration design for the SPEC board.
doc/ Documentation.
hostif/ Optional host interface.
tb/ Test benches.
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/ 0000775 0000000 0000000 00000000000 11632347016 0021364 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/Manifest.py 0000664 0000000 0000000 00000000361 11632347016 0023504 0 ustar 00root root 0000000 0000000 files = [
"tdc_controller.vhd", "tdc_freqc.vhd", "tdc_psync.vhd",
"tdc_channelbank.vhd", "tdc_delayline.vhd", "tdc_lbc.vhd", "tdc_ringosc.vhd",
"tdc_channel.vhd", "tdc_divider.vhd", "tdc_package.vhd", "tdc.vhd"
];
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/tdc.vhd 0000664 0000000 0000000 00000016740 11632347016 0022651 0 ustar 00root root 0000000 0000000 -------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Top level module
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-17 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- DESCRIPTION:
-- Top level module of the TDC core, contains all logic except the optional
-- host interface.
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.tdc_package.all;
entity tdc is
generic(
-- Number of channels.
g_CHANNEL_COUNT : positive := 2;
-- Number of CARRY4 elements per channel.
g_CARRY4_COUNT : positive := 100;
-- Number of raw output bits.
g_RAW_COUNT : positive := 9;
-- Number of fractional part bits.
g_FP_COUNT : positive := 13;
-- Number of coarse counter bits.
g_COARSE_COUNT : positive := 25;
-- Length of each ring oscillator.
g_RO_LENGTH : positive := 20;
-- Frequency counter width.
g_FCOUNTER_WIDTH : positive := 13;
-- Frequency counter timer width.
g_FTIMER_WIDTH : positive := 10
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
ready_o : out std_logic;
-- Coarse counter control.
cc_rst_i : in std_logic;
cc_cy_o : out std_logic;
-- Per-channel deskew inputs.
deskew_i : in std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
-- Per-channel signal inputs.
signal_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
calib_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
-- Per-channel detection outputs.
detect_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
polarity_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
raw_o : out std_logic_vector(g_CHANNEL_COUNT*g_RAW_COUNT-1 downto 0);
fp_o : out std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
-- Debug interface.
freeze_req_i : in std_logic;
freeze_ack_o : out std_logic;
cs_next_i : in std_logic;
cs_last_o : out std_logic;
calib_sel_i : in std_logic;
lut_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
his_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
his_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
oc_start_i : in std_logic;
oc_ready_o : out std_logic;
oc_freq_o : out std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
oc_sfreq_o : out std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0)
);
end entity;
architecture rtl of tdc is
signal cs_next : std_logic;
signal cs_next_c : std_logic;
signal cs_last : std_logic;
signal calib_sel : std_logic;
signal calib_sel_c : std_logic;
signal lut_a : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal lut_a_c : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal lut_we : std_logic;
signal lut_d_w : std_logic_vector(g_FP_COUNT-1 downto 0);
signal lut_d_r : std_logic_vector(g_FP_COUNT-1 downto 0);
signal c_detect : std_logic;
signal c_raw : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal his_a : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal his_a_c : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal his_we : std_logic;
signal his_d_w : std_logic_vector(g_FP_COUNT-1 downto 0);
signal his_d_r : std_logic_vector(g_FP_COUNT-1 downto 0);
signal oc_start : std_logic;
signal oc_start_c : std_logic;
signal oc_ready : std_logic;
signal oc_freq : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
signal oc_store : std_logic;
signal oc_sfreq : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
signal freeze_ack : std_logic;
begin
cmp_channelbank: tdc_channelbank
generic map(
g_CHANNEL_COUNT => g_CHANNEL_COUNT,
g_CARRY4_COUNT => g_CARRY4_COUNT,
g_RAW_COUNT => g_RAW_COUNT,
g_FP_COUNT => g_FP_COUNT,
g_COARSE_COUNT => g_COARSE_COUNT,
g_RO_LENGTH => g_RO_LENGTH,
g_FCOUNTER_WIDTH => g_FCOUNTER_WIDTH,
g_FTIMER_WIDTH => g_FTIMER_WIDTH
)
port map(
clk_i => clk_i,
reset_i => reset_i,
cc_rst_i => cc_rst_i,
cc_cy_o => cc_cy_o,
next_i => cs_next,
last_o => cs_last,
calib_sel_i => calib_sel,
deskew_i => deskew_i,
signal_i => signal_i,
calib_i => calib_i,
detect_o => detect_o,
polarity_o => polarity_o,
raw_o => raw_o,
fp_o => fp_o,
lut_a_i => lut_a,
lut_we_i => lut_we,
lut_d_i => lut_d_w,
lut_d_o => lut_d_r,
c_detect_o => c_detect,
c_raw_o => c_raw,
his_a_i => his_a,
his_we_i => his_we,
his_d_i => his_d_w,
his_d_o => his_d_r,
oc_start_i => oc_start,
oc_ready_o => oc_ready,
oc_freq_o => oc_freq,
oc_store_i => oc_store,
oc_sfreq_o => oc_sfreq
);
cmp_controller: tdc_controller
generic map(
g_RAW_COUNT => g_RAW_COUNT,
g_FP_COUNT => g_FP_COUNT,
g_FCOUNTER_WIDTH => g_FCOUNTER_WIDTH
)
port map(
clk_i => clk_i,
reset_i => reset_i,
ready_o => ready_o,
next_o => cs_next_c,
last_i => cs_last,
calib_sel_o => calib_sel_c,
lut_a_o => lut_a_c,
lut_we_o => lut_we,
lut_d_o => lut_d_w,
c_detect_i => c_detect,
c_raw_i => c_raw,
his_a_o => his_a_c,
his_we_o => his_we,
his_d_o => his_d_w,
his_d_i => his_d_r,
oc_start_o => oc_start_c,
oc_ready_i => oc_ready,
oc_freq_i => oc_freq,
oc_store_o => oc_store,
oc_sfreq_i => oc_sfreq,
freeze_req_i => freeze_req_i,
freeze_ack_o => freeze_ack
);
-- Debug interface signals.
cs_next <= cs_next_i when (freeze_ack = '1') else cs_next_c;
calib_sel <= calib_sel_i when (freeze_ack = '1') else calib_sel_c;
lut_a <= lut_a_i when (freeze_ack = '1') else lut_a_c;
his_a <= his_a_i when (freeze_ack = '1') else his_a_c;
oc_start <= oc_start_i when (freeze_ack = '1') else oc_start_c;
freeze_ack_o <= freeze_ack;
cs_last_o <= cs_last;
lut_d_o <= lut_d_r;
his_d_o <= his_d_r;
oc_ready_o <= oc_ready;
oc_freq_o <= oc_freq;
oc_sfreq_o <= oc_sfreq;
end architecture;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/tdc_channel.vhd 0000664 0000000 0000000 00000014111 11632347016 0024327 0 ustar 00root root 0000000 0000000 -------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_channel
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Per-channel processing
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-03 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- DESCRIPTION:
-- This contains the elements needed for each channel:
-- * Delay line
-- * Encoder
-- * LUT
-- * Deskew stage
-- * Online calibration ring oscillator
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.tdc_package.all;
use work.genram_pkg.all;
entity tdc_channel is
generic(
-- Number of CARRY4 elements.
g_CARRY4_COUNT : positive;
-- Number of raw output bits.
g_RAW_COUNT : positive;
-- Number of fractional part bits.
g_FP_COUNT : positive;
-- Number of coarse counter bits.
g_COARSE_COUNT : positive;
-- Length of the ring oscillator.
g_RO_LENGTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
-- Coarse counter and deskew inputs.
coarse_i : in std_logic_vector(g_COARSE_COUNT-1 downto 0);
deskew_i : in std_logic_vector((g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
-- Signal input.
signal_i : in std_logic;
calib_i : in std_logic;
calib_sel_i : in std_logic;
-- Detection outputs.
detect_o : out std_logic;
polarity_o : out std_logic;
raw_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
fp_o : out std_logic_vector((g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
-- LUT access.
lut_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_we_i : in std_logic;
lut_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0);
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
-- Calibration ring oscillator.
ro_en_i : in std_logic;
ro_clk_o : out std_logic
);
end entity;
architecture rtl of tdc_channel is
signal calib_sel_d : std_logic;
signal muxed_signal : std_logic;
signal taps : std_logic_vector(4*g_CARRY4_COUNT-1 downto 0);
signal polarity : std_logic;
signal polarity_d1 : std_logic;
signal polarity_d2 : std_logic;
signal detect_d1 : std_logic;
signal raw : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal raw_d1 : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal raw_d2 : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal lut : std_logic_vector(g_FP_COUNT-1 downto 0);
begin
-- register calibration select signal to avoid glitches
process(clk_i)
begin
if rising_edge(clk_i) then
calib_sel_d <= calib_sel_i;
end if;
end process;
with calib_sel_d select
muxed_signal <= calib_i when '1', signal_i when others;
cmp_delayline: tdc_delayline
generic map(
g_WIDTH => g_CARRY4_COUNT
)
port map(
clk_i => clk_i,
reset_i => reset_i,
signal_i => muxed_signal,
taps_o => taps
);
-- TODO: reorder bits by increasing delays
cmp_lbc: tdc_lbc
generic map(
g_N => g_RAW_COUNT,
g_NIN => g_CARRY4_COUNT*4
)
port map(
clk_i => clk_i,
reset_i => reset_i,
d_i => taps,
polarity_o => polarity,
count_o => raw
);
cmp_lut: generic_dpram
generic map(
g_data_width => g_FP_COUNT,
g_size => 2**g_RAW_COUNT,
g_with_byte_enable => false,
g_addr_conflict_resolution => "read_first",
g_init_file => "",
g_dual_clock => false
)
port map(
clka_i => clk_i,
clkb_i => '0',
wea_i => '0',
bwea_i => (others => '0'),
aa_i => raw,
da_i => (others => '0'),
qa_o => lut,
web_i => lut_we_i,
bweb_i => (others => '0'),
ab_i => lut_a_i,
db_i => lut_d_i,
qb_o => lut_d_o
);
cmp_ringosc: tdc_ringosc
generic map(
g_LENGTH => g_RO_LENGTH
)
port map(
en_i => ro_en_i,
clk_o => ro_clk_o
);
detect_d1 <= polarity_d1 xor polarity_d2;
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
detect_o <= '0';
polarity_d1 <= '1';
polarity_d2 <= '1';
raw_d1 <= (others => '0');
raw_d2 <= (others => '0');
else
detect_o <= detect_d1;
polarity_d1 <= polarity;
raw_d1 <= raw;
if detect_d1 = '1' then
polarity_d2 <= polarity_d1;
raw_d2 <= raw_d1;
end if;
end if;
end if;
end process;
polarity_o <= polarity_d2;
raw_o <= raw_d2;
-- Combine coarse counter value and deskew.
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
fp_o <= (others => '0');
else
if detect_d1 = '1' then
fp_o <= std_logic_vector(
unsigned(coarse_i & (lut'range => '0'))
- unsigned(lut)
+ unsigned(deskew_i));
end if;
end if;
end if;
end process;
end architecture;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/tdc_channelbank.vhd 0000664 0000000 0000000 00000027616 11632347016 0025201 0 ustar 00root root 0000000 0000000 -------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_channelbank
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Channel bank
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-18 SB Added histogram
-- 2011-08-17 SB Added frequency counter
-- 2011-08-08 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- DESCRIPTION:
-- This module instantiates all the channels and provides a control interface
-- independent of the number of channels.
-- It provides a simple two-wire interface to select the current channel to
-- operate one, using the next_i (switch to next channel) and last_o (current
-- channel is the current channel, next channel is the first channel).
-- It provides multiplexed access to the LUT of the current channel, to the
-- histogram of the current channel, and to the ring oscillator frequency
-- of the current channel.
--
-- To save resources:
-- * the histogram is implemented as one large block RAM common to all
-- channels
-- * the frequency counter logic is shared among all channels, each channel
-- only implements a ring oscillator.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.tdc_package.all;
use work.genram_pkg.all;
entity tdc_channelbank is
generic(
-- Number of channels.
g_CHANNEL_COUNT : positive;
-- Number of CARRY4 elements per channel.
g_CARRY4_COUNT : positive;
-- Number of raw output bits.
g_RAW_COUNT : positive;
-- Number of fractional part bits.
g_FP_COUNT : positive;
-- Number of coarse counter bits.
g_COARSE_COUNT : positive;
-- Length of each ring oscillator.
g_RO_LENGTH : positive;
-- Frequency counter width.
g_FCOUNTER_WIDTH : positive;
-- Frequency counter timer width.
g_FTIMER_WIDTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
-- Control.
cc_rst_i : in std_logic;
cc_cy_o : out std_logic;
next_i : in std_logic;
last_o : out std_logic;
calib_sel_i : in std_logic;
-- Per-channel deskew inputs.
deskew_i : in std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
-- Per-channel signal inputs.
signal_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
calib_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
-- Per-channel detection outputs.
detect_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
polarity_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
raw_o : out std_logic_vector(g_CHANNEL_COUNT*g_RAW_COUNT-1 downto 0);
fp_o : out std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
-- LUT access.
lut_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_we_i : in std_logic;
lut_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0);
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
-- Histogram.
c_detect_o : out std_logic;
c_raw_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
his_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
his_we_i : in std_logic;
his_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0);
his_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
-- Online calibration.
oc_start_i : in std_logic;
oc_ready_o : out std_logic;
oc_freq_o : out std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
oc_store_i : in std_logic;
oc_sfreq_o : out std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0)
);
end entity;
architecture rtl of tdc_channelbank is
signal detect : std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
signal raw : std_logic_vector(g_CHANNEL_COUNT*g_RAW_COUNT-1 downto 0);
signal coarse_counter : std_logic_vector(g_COARSE_COUNT-1 downto 0);
signal current_channel_onehot : std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
signal current_channel : std_logic_vector(f_log2_size(g_CHANNEL_COUNT)-1 downto 0);
signal lut_d_o_s : std_logic_vector(g_CHANNEL_COUNT*g_FP_COUNT-1 downto 0);
signal his_full_a : std_logic_vector(f_log2_size(g_CHANNEL_COUNT)+g_RAW_COUNT-1 downto 0);
signal ro_clk_s : std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
signal ro_clk : std_logic;
signal freq : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
signal sfreq_s : std_logic_vector(g_CHANNEL_COUNT*g_FCOUNTER_WIDTH-1 downto 0);
begin
-- Per-channel processing.
g_channels: for i in 0 to g_CHANNEL_COUNT-1 generate
signal this_calib_sel : std_logic;
signal this_lut_we : std_logic;
begin
this_calib_sel <= current_channel_onehot(i) and calib_sel_i;
this_lut_we <= current_channel_onehot(i) and lut_we_i;
cmp_channel: tdc_channel
generic map(
g_CARRY4_COUNT => g_CARRY4_COUNT,
g_RAW_COUNT => g_RAW_COUNT,
g_FP_COUNT => g_FP_COUNT,
g_COARSE_COUNT => g_COARSE_COUNT,
g_RO_LENGTH => g_RO_LENGTH
)
port map(
clk_i => clk_i,
reset_i => reset_i,
coarse_i => coarse_counter,
deskew_i =>
deskew_i((i+1)*(g_COARSE_COUNT+g_FP_COUNT)-1 downto i*(g_COARSE_COUNT+g_FP_COUNT)),
signal_i => signal_i(i),
calib_i => calib_i(i),
calib_sel_i => this_calib_sel,
detect_o => detect(i),
polarity_o => polarity_o(i),
raw_o => raw((i+1)*g_RAW_COUNT-1 downto i*g_RAW_COUNT),
fp_o =>
fp_o((i+1)*(g_COARSE_COUNT+g_FP_COUNT)-1 downto i*(g_COARSE_COUNT+g_FP_COUNT)),
lut_a_i => lut_a_i,
lut_we_i => this_lut_we,
lut_d_i => lut_d_i,
lut_d_o => lut_d_o_s((i+1)*g_FP_COUNT-1 downto i*g_FP_COUNT),
ro_en_i => current_channel_onehot(i),
ro_clk_o => ro_clk_s(i)
);
end generate;
detect_o <= detect;
raw_o <= raw;
-- Histogram memory.
cmp_histogram: generic_spram
generic map(
g_data_width => g_FP_COUNT,
g_size => g_CHANNEL_COUNT*2**g_RAW_COUNT,
g_with_byte_enable => false,
g_init_file => "",
g_addr_conflict_resolution => "read_first"
)
port map(
rst_n_i => '1',
clk_i => clk_i,
bwe_i => (others => '0'),
we_i => his_we_i,
a_i => his_full_a,
d_i => his_d_i,
q_o => his_d_o
);
his_full_a <= current_channel & his_a_i;
-- Frequency counter.
cmp_freqc: tdc_freqc
generic map(
g_COUNTER_WIDTH => g_FCOUNTER_WIDTH,
g_TIMER_WIDTH => g_FTIMER_WIDTH
)
port map(
clk_i => clk_i,
reset_i => reset_i,
clk_m_i => ro_clk,
start_i => oc_start_i,
ready_o => oc_ready_o,
freq_o => freq
);
oc_freq_o <= freq;
-- Coarse counter.
process(clk_i)
begin
if rising_edge(clk_i) then
if (reset_i = '1') or (cc_rst_i = '1') then
coarse_counter <= (coarse_counter'range => '0');
cc_cy_o <= '0';
else
coarse_counter <= std_logic_vector(unsigned(coarse_counter) + 1);
if coarse_counter = (coarse_counter'range => '1') then
cc_cy_o <= '1';
else
cc_cy_o <= '0';
end if;
end if;
end if;
end process;
-- Combine LUT outputs.
process(lut_d_o_s, current_channel_onehot)
variable v_lut_d_o: std_logic_vector(g_FP_COUNT-1 downto 0);
begin
v_lut_d_o := (v_lut_d_o'range => '0');
for i in 0 to g_CHANNEL_COUNT-1 loop
if current_channel_onehot(i) = '1' then
v_lut_d_o := v_lut_d_o or lut_d_o_s((i+1)*g_FP_COUNT-1 downto i*g_FP_COUNT);
end if;
end loop;
lut_d_o <= v_lut_d_o;
end process;
-- Select detect and raw outputs for histogram generation.
process(detect, raw, current_channel_onehot)
variable v_c_detect_o : std_logic;
variable v_c_raw_o : std_logic_vector(g_RAW_COUNT-1 downto 0);
begin
v_c_detect_o := '0';
v_c_raw_o := (v_c_raw_o'range => '0');
for i in 0 to g_CHANNEL_COUNT-1 loop
if current_channel_onehot(i) = '1' then
v_c_detect_o := v_c_detect_o or detect(i);
v_c_raw_o := v_c_raw_o or raw((i+1)*g_RAW_COUNT-1 downto i*g_RAW_COUNT);
end if;
end loop;
c_detect_o <= v_c_detect_o;
c_raw_o <= v_c_raw_o;
end process;
-- Combine ring oscillator outputs. When disabled, a ring oscillator
-- outputs 0, so we can simply OR all outputs together.
ro_clk <= '0' when (ro_clk_s = (ro_clk_s'range => '0')) else '1';
-- Store and retrieve per-channel ring oscillator frequencies.
process(clk_i)
begin
if rising_edge(clk_i) then
if oc_store_i = '1' then
for i in 0 to g_CHANNEL_COUNT-1 loop
if current_channel_onehot(i) = '1' then
sfreq_s((i+1)*g_FCOUNTER_WIDTH-1 downto i*g_FCOUNTER_WIDTH) <= freq;
end if;
end loop;
end if;
end if;
end process;
process(sfreq_s, current_channel_onehot)
variable v_oc_sfreq_o: std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
begin
v_oc_sfreq_o := (v_oc_sfreq_o'range => '0');
for i in 0 to g_CHANNEL_COUNT-1 loop
if current_channel_onehot(i) = '1' then
v_oc_sfreq_o := v_oc_sfreq_o
or sfreq_s((i+1)*g_FCOUNTER_WIDTH-1 downto i*g_FCOUNTER_WIDTH);
end if;
end loop;
oc_sfreq_o <= v_oc_sfreq_o;
end process;
-- Generate channel selection signals.
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
current_channel_onehot <= (0 => '1', others => '0');
else
if next_i = '1' then
current_channel_onehot <=
std_logic_vector(rotate_left(unsigned(current_channel_onehot), 1));
end if;
end if;
end if;
end process;
last_o <= current_channel_onehot(g_CHANNEL_COUNT-1);
g_encode: if g_CHANNEL_COUNT > 1 generate
process(current_channel_onehot)
variable v_current_channel: std_logic_vector(f_log2_size(g_CHANNEL_COUNT)-1 downto 0);
begin
v_current_channel := (v_current_channel'range => '0');
for i in 0 to g_CHANNEL_COUNT-1 loop
if current_channel_onehot(i) = '1' then
v_current_channel := v_current_channel
or std_logic_vector(to_unsigned(i, v_current_channel'length));
end if;
end loop;
current_channel <= v_current_channel;
end process;
end generate;
end architecture;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/tdc_controller.vhd 0000664 0000000 0000000 00000026055 11632347016 0025114 0 ustar 00root root 0000000 0000000 -------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_controller
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Controller
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-19 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- DESCRIPTION:
-- This is the controller for the channel bank. It is in charge of sequencing
-- and performing the startup and online calibrations for all channels.
-- It books the histograms and computes and loads the LUTs of the channels.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.tdc_package.all;
entity tdc_controller is
generic(
g_RAW_COUNT : positive;
g_FP_COUNT : positive;
g_FCOUNTER_WIDTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
ready_o : out std_logic;
next_o : out std_logic;
last_i : in std_logic;
calib_sel_o : out std_logic;
lut_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_we_o : out std_logic;
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
c_detect_i : in std_logic;
c_raw_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
his_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
his_we_o : out std_logic;
his_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
his_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0);
oc_start_o : out std_logic;
oc_ready_i : in std_logic;
oc_freq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
oc_store_o : out std_logic;
oc_sfreq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
freeze_req_i : in std_logic;
freeze_ack_o : out std_logic
);
end entity;
architecture rtl of tdc_controller is
signal ready_p: std_logic;
signal hc_count : std_logic_vector(g_FP_COUNT-1 downto 0);
signal hc_reset : std_logic;
signal hc_dec : std_logic;
signal hc_zero : std_logic;
signal ha_count : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal ha_reset : std_logic;
signal ha_inc : std_logic;
signal ha_last : std_logic;
signal ha_sel : std_logic;
signal acc : std_logic_vector(g_FP_COUNT-1 downto 0);
signal acc_reset : std_logic;
signal acc_en : std_logic;
signal mul : std_logic_vector(g_FP_COUNT+g_FCOUNTER_WIDTH-1 downto 0);
signal mul_d1 : std_logic_vector(g_FP_COUNT+g_FCOUNTER_WIDTH-1 downto 0);
signal div_start : std_logic;
signal div_ready : std_logic;
signal div_divisor : std_logic_vector(g_FP_COUNT+g_FCOUNTER_WIDTH-1 downto 0);
signal div_quotient : std_logic_vector(g_FP_COUNT+g_FCOUNTER_WIDTH-1 downto 0);
signal div_qsat : std_logic_vector(g_FP_COUNT-1 downto 0);
type t_state is (
-- startup calibration
SC_NEWCHANNEL, SC_CLEARHIST, SC_READ, SC_UPDATE, SC_STOREF0,
-- online calibration
OC_STARTM, OC_WAITM, OC_WAITMUL1, OC_WAITMUL2, OC_STARTDIV, OC_WAITDIV, OC_WRITELUT, OC_NEXTCHANNEL,
-- freeze state (transfer control to debug interface)
FREEZE
);
signal state: t_state;
begin
-- generate ready signal
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
ready_o <= '0';
else
if ready_p = '1' then
ready_o <= '1';
end if;
end if;
end if;
end process;
-- count histogram entries when recording
process(clk_i)
begin
if rising_edge(clk_i) then
if hc_reset = '1' then
hc_count <= (hc_count'range => '1');
elsif hc_dec = '1' then
hc_count <= std_logic_vector(unsigned(hc_count) - 1);
end if;
end if;
end process;
hc_zero <= '1' when (hc_count = (hc_count'range => '0')) else '0';
-- generate histogram memory address and write data
process(clk_i)
begin
if rising_edge(clk_i) then
if ha_reset = '1' then
ha_count <= (ha_count'range => '0');
elsif ha_inc = '1' then
ha_count <= std_logic_vector(unsigned(ha_count) + 1);
end if;
end if;
end process;
ha_last <= '1' when (ha_count = (ha_count'range => '1')) else '0';
his_a_o <= ha_count when (ha_sel = '1') else c_raw_i;
his_d_o <= (his_d_o'range => '0') when (ha_sel = '1')
else std_logic_vector(unsigned(his_d_i) + 1);
-- accumulator
process(clk_i)
begin
if rising_edge(clk_i) then
if acc_reset = '1' then
acc <= (acc'range => '0');
elsif acc_en = '1' then
acc <= std_logic_vector(unsigned(acc) + unsigned(his_d_i));
end if;
end if;
end process;
-- multiplier
process(clk_i)
begin
if rising_edge(clk_i) then
mul <= std_logic_vector(unsigned(acc) * unsigned(oc_sfreq_i));
mul_d1 <= mul;
end if;
end process;
-- divider
cmp_divider: tdc_divider
generic map(
g_WIDTH => g_FP_COUNT+g_FCOUNTER_WIDTH
)
port map(
clk_i => clk_i,
reset_i => reset_i,
start_i => div_start,
dividend_i => mul_d1,
divisor_i => div_divisor,
ready_o => div_ready,
quotient_o => div_quotient,
remainder_o => open
);
div_divisor <= (g_FP_COUNT-1 downto 0 => '0') & oc_freq_i;
process(div_quotient)
begin
if div_quotient(g_FP_COUNT+g_FCOUNTER_WIDTH-1 downto g_FP_COUNT)
= (g_FCOUNTER_WIDTH-1 downto 0 => '0') then
div_qsat <= div_quotient(g_FP_COUNT-1 downto 0);
else -- saturate
div_qsat <= (div_qsat'range => '1');
end if;
end process;
-- generate LUT address and write data
lut_a_o <= std_logic_vector(unsigned(ha_count) + 1);
lut_d_o <= div_qsat;
-- main FSM
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
state <= SC_NEWCHANNEL;
else
case state is
when SC_NEWCHANNEL =>
state <= SC_CLEARHIST;
when SC_CLEARHIST =>
if ha_last = '1' then
state <= SC_READ;
end if;
when SC_READ =>
if c_detect_i = '1' then
state <= SC_UPDATE;
end if;
when SC_UPDATE =>
if hc_zero = '1' then
state <= SC_STOREF0;
else
state <= SC_READ;
end if;
when SC_STOREF0 =>
if oc_ready_i = '1' then
if last_i = '1' then
state <= OC_STARTM;
else
state <= SC_NEWCHANNEL;
end if;
end if;
when OC_STARTM =>
state <= OC_WAITM;
when OC_WAITM =>
if oc_ready_i = '1' then
state <= OC_WAITMUL1;
end if;
when OC_WAITMUL1 =>
state <= OC_WAITMUL2;
when OC_WAITMUL2 =>
state <= OC_STARTDIV;
when OC_STARTDIV =>
state <= OC_WAITDIV;
when OC_WAITDIV =>
if div_ready = '1' then
state <= OC_WRITELUT;
end if;
when OC_WRITELUT =>
if ha_last = '1' then
state <= OC_NEXTCHANNEL;
else
state <= OC_WAITMUL1;
end if;
when OC_NEXTCHANNEL =>
if freeze_req_i = '1' then
state <= FREEZE;
else
state <= OC_STARTM;
end if;
when FREEZE =>
if freeze_req_i = '0' then
state <= OC_STARTM;
end if;
end case;
end if;
end if;
end process;
process(state, hc_zero, oc_ready_i, last_i)
begin
ready_p <= '0';
hc_reset <= '0';
hc_dec <= '0';
ha_reset <= '0';
ha_inc <= '0';
ha_sel <= '0';
acc_reset <= '0';
acc_en <= '0';
div_start <= '0';
next_o <= '0';
calib_sel_o <= '0';
lut_we_o <= '0';
his_we_o <= '0';
oc_start_o <= '0';
oc_store_o <= '0';
freeze_ack_o <= '0';
case state is
when SC_NEWCHANNEL =>
hc_reset <= '1';
ha_reset <= '1';
when SC_CLEARHIST =>
calib_sel_o <= '1';
ha_inc <= '1';
ha_sel <= '1';
his_we_o <= '1';
when SC_READ =>
calib_sel_o <= '1';
when SC_UPDATE =>
calib_sel_o <= '1';
his_we_o <= '1';
hc_dec <= '1';
if hc_zero = '1' then
oc_start_o <= '1';
end if;
when SC_STOREF0 =>
if oc_ready_i = '1' then
oc_store_o <= '1';
next_o <= '1';
end if;
when OC_STARTM =>
oc_start_o <= '1';
ha_reset <= '1';
acc_reset <= '1';
when OC_WAITM =>
null;
when OC_WAITMUL1 =>
null;
when OC_WAITMUL2 =>
null;
when OC_STARTDIV =>
div_start <= '1';
when OC_WAITDIV =>
null;
when OC_WRITELUT =>
lut_we_o <= '1';
acc_en <= '1';
ha_inc <= '1';
when OC_NEXTCHANNEL =>
next_o <= '1';
if last_i = '1' then
ready_p <= '1';
end if;
when FREEZE =>
freeze_ack_o <= '1';
end case;
end process;
end architecture;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/tdc_delayline.vhd 0000664 0000000 0000000 00000006115 11632347016 0024672 0 ustar 00root root 0000000 0000000 -------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_delayline
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Delay line based on CARRY4 primitives
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-01 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- DESCRIPTION:
-- The delay line uses a carry chain. It is made up of CARRY4 primitives whose
-- CO outputs are registered by the dedicated D flip flops of the same slices.
-- The signal is injected at the CYINIT pin at the bottom of the carry chain.
-- The CARRY4 primitives have their S inputs hardwired to 1, which means the
-- carry chain becomes a delay line with the signal going unchanged through the
-- MUXCY elements. Since each CARRY4 contains four MUXCY elements, the delay
-- line has four times as many taps as there are CARRY4 primitives.
--
-- There is a second layer of registers to prevent metastability.
library ieee;
use ieee.std_logic_1164.all;
library unisim;
use unisim.vcomponents.all;
library work;
use work.tdc_package.all;
entity tdc_delayline is
generic(
-- Number of CARRY4 elements.
g_WIDTH: positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
signal_i : in std_logic;
taps_o : out std_logic_vector(4*g_WIDTH-1 downto 0)
);
end entity;
architecture rtl of tdc_delayline is
signal unreg : std_logic_vector(4*g_WIDTH-1 downto 0);
signal reg1 : std_logic_vector(4*g_WIDTH-1 downto 0);
begin
-- generate a carry chain
g_carry4: for i in 0 to g_WIDTH-1 generate
g_firstcarry4: if i = 0 generate
cmp_CARRY4: CARRY4 port map(
CO => unreg(3 downto 0),
CI => '0',
CYINIT => signal_i,
DI => "0000",
S => "1111"
);
end generate;
g_nextcarry4: if i > 0 generate
cmp_CARRY4: CARRY4 port map(
CO => unreg(4*(i+1)-1 downto 4*i),
CI => unreg(4*i-1),
CYINIT => '0',
DI => "0000",
S => "1111"
);
end generate;
end generate;
-- double latch the output
g_fd: for j in 0 to 4*g_WIDTH-1 generate
cmp_FDR_1: FDR
generic map(
INIT => '0'
)
port map(
C => clk_i,
R => reset_i,
D => unreg(j),
Q => reg1(j)
);
cmp_FDR_2: FDR
generic map(
INIT => '0'
)
port map(
C => clk_i,
R => reset_i,
D => reg1(j),
Q => taps_o(j)
);
end generate;
end architecture;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/tdc_divider.vhd 0000664 0000000 0000000 00000006353 11632347016 0024356 0 ustar 00root root 0000000 0000000 -------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_divider
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Multi-cycle unsigned integer divider
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-17 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- DESCRIPTION:
-- Sequentially computes the Euclidean division of dividend_i by divisor_i.
-- Returns quotient and remainder. Works with unsigned integers of g_WIDTH
-- bits each.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.tdc_package.all;
entity tdc_divider is
generic(
-- Number of bits of the operands and results.
g_WIDTH: positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
start_i : in std_logic;
dividend_i : in std_logic_vector(g_WIDTH-1 downto 0);
divisor_i : in std_logic_vector(g_WIDTH-1 downto 0);
ready_o : out std_logic;
quotient_o : out std_logic_vector(g_WIDTH-1 downto 0);
remainder_o : out std_logic_vector(g_WIDTH-1 downto 0)
);
end entity;
architecture rtl of tdc_divider is
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;
signal qr : std_logic_vector(2*g_WIDTH-1 downto 0);
signal counter : std_logic_vector(f_log2_size(g_WIDTH+1)-1 downto 0);
signal divisor_r : std_logic_vector(g_WIDTH-1 downto 0);
signal diff : std_logic_vector(g_WIDTH downto 0);
signal ready : std_logic;
begin
quotient_o <= qr(g_WIDTH-1 downto 0);
remainder_o <= qr(2*g_WIDTH-1 downto g_WIDTH);
ready <= '1' when (counter = (counter'range => '0')) else '0';
ready_o <= ready;
diff <= std_logic_vector(unsigned(qr(2*g_WIDTH-1 downto g_WIDTH-1))
- unsigned("0" & divisor_r));
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
qr <= (qr'range => '0');
counter <= (counter'range => '0');
divisor_r <= (divisor_r'range => '0');
else
if start_i = '1' then
counter <= std_logic_vector(to_unsigned(g_WIDTH, counter'length));
qr <= (g_WIDTH-1 downto 0 => '0') & dividend_i;
divisor_r <= divisor_i;
elsif ready = '0' then
if diff(g_WIDTH) = '1' then
qr <= qr(2*g_WIDTH-2 downto 0) & "0";
else
qr <= diff(g_WIDTH-1 downto 0) & qr(g_WIDTH-2 downto 0) & "1";
end if;
counter <= std_logic_vector(unsigned(counter) - 1);
end if;
end if;
end if;
end process;
end architecture;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/tdc_freqc.vhd 0000664 0000000 0000000 00000011725 11632347016 0024027 0 ustar 00root root 0000000 0000000 -------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_freqc
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Frequency counter
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-13 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- DESCRIPTION:
-- Counts the number of rising edges in clk_m_i for 2^g_TIMER_WIDTH-1 periods
-- of clk_i and returns the result. All signals are synchronous to clk_i.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.tdc_package.all;
entity tdc_freqc is
generic(
g_COUNTER_WIDTH : positive;
g_TIMER_WIDTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
clk_m_i : in std_logic;
start_i : in std_logic;
ready_o : out std_logic;
freq_o : out std_logic_vector(g_COUNTER_WIDTH-1 downto 0)
);
end entity;
architecture rtl of tdc_freqc is
-- clk_m domain
signal m_counter : std_logic_vector(g_COUNTER_WIDTH-1 downto 0);
signal m_start : std_logic;
signal m_stop : std_logic;
signal m_started : std_logic;
-- clk domain
signal start : std_logic;
signal stop : std_logic;
signal stop_ack : std_logic;
signal counter_r : std_logic_vector(g_COUNTER_WIDTH-1 downto 0);
signal timer : std_logic_vector(g_TIMER_WIDTH-1 downto 0);
signal timer_start : std_logic;
signal timer_done : std_logic;
type t_state is (IDLE, MEASURING, TERMINATING);
signal state : t_state;
-- Prevent inference of a SRL* primitive, which does not
-- have good metastability resistance.
attribute keep: string;
attribute keep of counter_r: signal is "true";
begin
-- clk_m clock domain.
process(clk_m_i)
begin
if rising_edge(clk_m_i) then
if (m_started = '1') and (m_stop = '0') then
m_counter <= std_logic_vector(unsigned(m_counter) + 1);
end if;
if m_start = '1' then
m_started <= '1';
m_counter <= (m_counter'range => '0');
end if;
if m_stop = '1' then
m_started <= '0';
end if;
end if;
end process;
-- Synchronisers.
cmp_sync_start: tdc_psync
port map(
clk_src_i => clk_i,
p_i => start,
clk_dst_i => clk_m_i,
p_o => m_start
);
cmp_sync_stop: tdc_psync
port map(
clk_src_i => clk_i,
p_i => stop,
clk_dst_i => clk_m_i,
p_o => m_stop
);
cmp_sync_stop_ack: tdc_psync
port map(
clk_src_i => clk_m_i,
p_i => m_stop,
clk_dst_i => clk_i,
p_o => stop_ack
);
process(clk_i)
begin
if rising_edge(clk_i) then
counter_r <= m_counter;
freq_o <= counter_r;
end if;
end process;
-- Controller.
process(clk_i)
begin
if rising_edge(clk_i) then
if timer_start = '1' then
timer <= (timer'range => '1');
elsif timer_done = '0' then
timer <= std_logic_vector(unsigned(timer) - 1);
end if;
end if;
end process;
timer_done <= '1' when (timer = (timer'range => '0')) else '0';
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
state <= IDLE;
else
case state is
when IDLE =>
if start_i = '1' then
state <= MEASURING;
end if;
when MEASURING =>
if timer_done = '1' then
state <= TERMINATING;
end if;
when TERMINATING =>
if stop_ack = '1' then
state <= IDLE;
end if;
end case;
end if;
end if;
end process;
process(state, start_i, timer_done, stop_ack)
begin
ready_o <= '0';
start <= '0';
stop <= '0';
timer_start <= '0';
case state is
when IDLE =>
ready_o <= '1';
if start_i = '1' then
start <= '1';
timer_start <= '1';
end if;
when MEASURING =>
if timer_done = '1' then
stop <= '1';
end if;
when TERMINATING =>
null;
end case;
end process;
end architecture;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/tdc_lbc.vhd 0000664 0000000 0000000 00000010123 11632347016 0023456 0 ustar 00root root 0000000 0000000 -------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_lbc
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Leading bit counter
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-01 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- DESCRIPTION:
-- Encoder for the delay line. Counts the number of leading bits equal to the
-- current polarity. The current polarity is the opposite of the most
-- significant bit of the input vector from the previous cycle.
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.tdc_package.all;
entity tdc_lbc is
generic(
-- Number of output bits.
g_N : positive;
-- Number of input bits. Maximum is 2^g_N-1.
g_NIN: positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
d_i : in std_logic_vector(g_NIN-1 downto 0);
polarity_o : out std_logic;
count_o : out std_logic_vector(g_N-1 downto 0)
);
end entity;
architecture rtl of tdc_lbc is
-- "Count leading symbol" function inspired by the post by Ulf Samuelsson
-- http://www.velocityreviews.com/forums/t25846-p4-how-to-count-zeros-in-registers.html
--
-- The idea is to use a divide-and-conquer approach to process a 2^N bit number.
-- We split the number in two equal halves of 2^(N-1) bits:
-- MMMMLLLL
-- then, we check if all bits of MMMM are of the counted symbol.
-- If it is,
-- then the number of leading symbols is 2^(N-1) + CLS(LLLL)
-- If it is not,
-- then the number of leading symbols is CLS(MMMM)
-- Recursion stops with CLS(0)=0 and CLS(1)=1.
--
-- If at least one bit of the input is not the symbol, we never propagate a carry
-- and the additions can be replaced by OR's, giving the result bit per bit.
-- We assume here an implicit LSB with a !symbol value, and work with inputs
-- widths that are a power of 2 minus one.
function f_cls(d: std_logic_vector; symbol: std_logic) return std_logic_vector is
variable v_d: std_logic_vector(d'length-1 downto 0);
begin
v_d := d; -- fix indices
if v_d'length = 1 then
if v_d(0) = symbol then
return "1";
else
return "0";
end if;
else
if v_d(v_d'length-1 downto v_d'length/2) = (v_d'length-1 downto v_d'length/2 => symbol) then
return "1" & f_cls(v_d(v_d'length/2-1 downto 0), symbol);
else
return "0" & f_cls(v_d(v_d'length-1 downto v_d'length/2+1), symbol);
end if;
end if;
end function;
signal polarity : std_logic;
signal polarity_d1 : std_logic;
signal polarity_d2 : std_logic;
signal count_reg : std_logic_vector(g_N-1 downto 0);
signal d_completed : std_logic_vector(2**g_N-2 downto 0);
-- enable retiming
attribute register_balancing: string;
attribute register_balancing of count_reg: signal is "backward";
attribute register_balancing of count_o: signal is "backward";
begin
g_expand: if g_NIN < 2**g_N-1 generate
d_completed <= d_i & (2**g_N-1-g_NIN-1 downto 0 => not polarity);
end generate;
g_dontexpand: if g_NIN = 2**g_N-1 generate
d_completed <= d_i;
end generate;
process(clk_i)
begin
if rising_edge(clk_i) then
if reset_i = '1' then
polarity <= '1';
polarity_d1 <= '1';
polarity_d2 <= '1';
count_reg <= (others => '0');
count_o <= (others => '0');
else
polarity <= not d_completed(2**g_N-2);
polarity_d1 <= polarity;
polarity_d2 <= polarity_d1;
count_reg <= f_cls(d_completed, polarity);
count_o <= count_reg;
end if;
end if;
end process;
polarity_o <= polarity_d2;
end architecture;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/tdc_package.vhd 0000664 0000000 0000000 00000022065 11632347016 0024321 0 ustar 00root root 0000000 0000000 -------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_package
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Component declarations for the TDC core
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-03 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- DESCRIPTION:
-- This contains component declarations for all the modules of the TDC core.
-- It is used both internally to instantiate modules, and by the user to
-- instantiate the top-level "tdc" module.
library ieee;
use ieee.std_logic_1164.all;
package tdc_package is
component tdc is
generic(
g_CHANNEL_COUNT : positive := 2;
g_CARRY4_COUNT : positive := 100;
g_RAW_COUNT : positive := 9;
g_FP_COUNT : positive := 13;
g_COARSE_COUNT : positive := 25;
g_RO_LENGTH : positive := 20;
g_FCOUNTER_WIDTH : positive := 13;
g_FTIMER_WIDTH : positive := 10
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
ready_o : out std_logic;
cc_rst_i : in std_logic;
cc_cy_o : out std_logic;
deskew_i : in std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
signal_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
calib_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
detect_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
polarity_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
raw_o : out std_logic_vector(g_CHANNEL_COUNT*g_RAW_COUNT-1 downto 0);
fp_o : out std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
freeze_req_i : in std_logic;
freeze_ack_o : out std_logic;
cs_next_i : in std_logic;
cs_last_o : out std_logic;
calib_sel_i : in std_logic;
lut_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
his_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
his_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
oc_start_i : in std_logic;
oc_ready_o : out std_logic;
oc_freq_o : out std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
oc_sfreq_o : out std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0)
);
end component;
component tdc_controller is
generic(
g_RAW_COUNT : positive;
g_FP_COUNT : positive;
g_FCOUNTER_WIDTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
ready_o : out std_logic;
next_o : out std_logic;
last_i : in std_logic;
calib_sel_o : out std_logic;
lut_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_we_o : out std_logic;
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
c_detect_i : in std_logic;
c_raw_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
his_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
his_we_o : out std_logic;
his_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
his_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0);
oc_start_o : out std_logic;
oc_ready_i : in std_logic;
oc_freq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
oc_store_o : out std_logic;
oc_sfreq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
freeze_req_i : in std_logic;
freeze_ack_o : out std_logic
);
end component;
component tdc_channelbank is
generic(
g_CHANNEL_COUNT : positive;
g_CARRY4_COUNT : positive;
g_RAW_COUNT : positive;
g_FP_COUNT : positive;
g_COARSE_COUNT : positive;
g_RO_LENGTH : positive;
g_FCOUNTER_WIDTH : positive;
g_FTIMER_WIDTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
cc_rst_i : in std_logic;
cc_cy_o : out std_logic;
next_i : in std_logic;
last_o : out std_logic;
calib_sel_i : in std_logic;
deskew_i : in std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
signal_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
calib_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
detect_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
polarity_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
raw_o : out std_logic_vector(g_CHANNEL_COUNT*g_RAW_COUNT-1 downto 0);
fp_o : out std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
lut_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_we_i : in std_logic;
lut_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0);
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
c_detect_o : out std_logic;
c_raw_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
his_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
his_we_i : in std_logic;
his_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0);
his_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
oc_start_i : in std_logic;
oc_ready_o : out std_logic;
oc_freq_o : out std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
oc_store_i : in std_logic;
oc_sfreq_o : out std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0)
);
end component;
component tdc_freqc is
generic(
g_COUNTER_WIDTH : positive;
g_TIMER_WIDTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
clk_m_i : in std_logic;
start_i : in std_logic;
ready_o : out std_logic;
freq_o : out std_logic_vector(g_COUNTER_WIDTH-1 downto 0)
);
end component;
component tdc_channel is
generic(
g_CARRY4_COUNT : positive;
g_RAW_COUNT : positive;
g_FP_COUNT : positive;
g_COARSE_COUNT : positive;
g_RO_LENGTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
coarse_i : in std_logic_vector(g_COARSE_COUNT-1 downto 0);
deskew_i : in std_logic_vector((g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
signal_i : in std_logic;
calib_i : in std_logic;
calib_sel_i : in std_logic;
detect_o : out std_logic;
polarity_o : out std_logic;
raw_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
fp_o : out std_logic_vector((g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
lut_a_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_we_i : in std_logic;
lut_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0);
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
ro_en_i : in std_logic;
ro_clk_o : out std_logic
);
end component;
component tdc_ringosc is
generic(
g_LENGTH: positive
);
port(
en_i : in std_logic;
clk_o : out std_logic
);
end component;
component tdc_lbc is
generic(
g_N : positive;
g_NIN: positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
d_i : in std_logic_vector(g_NIN-1 downto 0);
polarity_o : out std_logic;
count_o : out std_logic_vector(g_N-1 downto 0)
);
end component;
component tdc_delayline is
generic(
g_WIDTH : positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
signal_i : in std_logic;
taps_o : out std_logic_vector(4*g_WIDTH-1 downto 0)
);
end component;
component tdc_divider is
generic(
g_WIDTH: positive
);
port(
clk_i : in std_logic;
reset_i : in std_logic;
start_i : in std_logic;
dividend_i : in std_logic_vector(g_WIDTH-1 downto 0);
divisor_i : in std_logic_vector(g_WIDTH-1 downto 0);
ready_o : out std_logic;
quotient_o : out std_logic_vector(g_WIDTH-1 downto 0);
remainder_o : out std_logic_vector(g_WIDTH-1 downto 0)
);
end component;
component tdc_psync is
port(
clk_src_i : in std_logic;
p_i : in std_logic;
clk_dst_i : in std_logic;
p_o : out std_logic
);
end component;
end package;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/tdc_psync.vhd 0000664 0000000 0000000 00000004501 11632347016 0024055 0 ustar 00root root 0000000 0000000 -------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_psync
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Pulse synchronizer
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-14 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- DESCRIPTION:
-- Converts a single clock cycle pulse in the clk_src_i domain into a single
-- clock cycle pulse in the clk_dst_i domain.
-- It does so by converting the pulse into a level change, synchronizing
-- this level change into the destination domain by double latching, and
-- finally restoring the pulse in the destination domain.
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.tdc_package.all;
entity tdc_psync is
port(
clk_src_i : in std_logic;
p_i : in std_logic;
clk_dst_i : in std_logic;
p_o : out std_logic
);
end entity;
architecture rtl of tdc_psync is
-- Initialize registers at FPGA configuration.
signal level : std_logic := '0';
signal level_d1 : std_logic := '0';
signal level_d2 : std_logic := '0';
signal level_d3 : std_logic := '0';
-- Prevent inference of a SRL* primitive, which does not
-- have good metastability resistance.
attribute keep: string;
attribute keep of level_d1: signal is "true";
attribute keep of level_d2: signal is "true";
attribute keep of level_d3: signal is "true";
begin
-- Convert incoming pulses into level flips.
process(clk_src_i)
begin
if rising_edge(clk_src_i) then
if p_i = '1' then
level <= not level;
end if;
end if;
end process;
-- Synchronize level to clk_dst domain and register.
process(clk_dst_i)
begin
if rising_edge(clk_dst_i) then
level_d1 <= level;
level_d2 <= level_d1;
level_d3 <= level_d2;
end if;
end process;
-- Convert level flips back into pulses synchronous to clk_dst domain.
p_o <= level_d2 xor level_d3;
end architecture;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/core/tdc_ringosc.vhd 0000664 0000000 0000000 00000004456 11632347016 0024376 0 ustar 00root root 0000000 0000000 -------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc_ringosc
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Ring oscillator based on LUT primitives
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
-- 2011-08-05 SB Created file
-------------------------------------------------------------------------------
-- Copyright (C) 2011 Sebastien Bourdeauducq
-- DESCRIPTION:
-- Ring oscillator built by chaining together an odd number of LUTs used
-- as inverters. The first LUT has a second input which forces its output
-- to 0. This is useful to initialize the ring oscillator and make sure
-- that only one wave is traveling through it, and to force the output of the
-- oscillator to 0 at any time.
library ieee;
use ieee.std_logic_1164.all;
library unisim;
use unisim.vcomponents.all;
library work;
use work.tdc_package.all;
entity tdc_ringosc is
generic(
-- Number of LUT elements. Must be odd!
g_LENGTH: positive
);
port(
-- Enable/reset_n input. The oscillator should be reset at least once.
-- When disabled, the output is 0.
en_i : in std_logic;
-- Oscillator output.
clk_o : out std_logic
);
end entity;
architecture rtl of tdc_ringosc is
signal s: std_logic_vector(g_LENGTH downto 0);
attribute keep: string;
attribute keep of s: signal is "true";
begin
g_luts: for i in 0 to g_LENGTH-1 generate
g_firstlut: if i = 0 generate
cmp_LUT: LUT2
generic map(
INIT => "0100"
)
port map(
I0 => s(i),
I1 => en_i,
O => s(i+1)
);
end generate;
g_nextlut: if i > 0 generate
cmp_LUT: LUT1
generic map(
INIT => "01"
)
port map(
I0 => s(i),
O => s(i+1)
);
end generate;
end generate;
s(0) <= s(g_LENGTH);
clk_o <= s(g_LENGTH);
end architecture;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/ 0000775 0000000 0000000 00000000000 11632347016 0021360 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/ 0000775 0000000 0000000 00000000000 11632347016 0022632 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/ 0000775 0000000 0000000 00000000000 11632347016 0023564 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/rtl/ 0000775 0000000 0000000 00000000000 11632347016 0024365 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/rtl/lm32_include.v 0000664 0000000 0000000 00000027275 11632347016 0027051 0 ustar 00root root 0000000 0000000 // =============================================================================
// COPYRIGHT NOTICE
// Copyright 2006 (c) Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
// This confidential and proprietary software may be used only as authorised by
// a licensing agreement from Lattice Semiconductor Corporation.
// The entire notice above must be reproduced on all authorized copies and
// copies may only be made to the extent permitted by a licensing agreement from
// Lattice Semiconductor Corporation.
//
// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada)
// 5555 NE Moore Court 408-826-6000 (other locations)
// Hillsboro, OR 97124 web : http://www.latticesemi.com/
// U.S.A email: techsupport@latticesemi.com
// =============================================================================/
// FILE DETAILS
// Project : LatticeMico32
// File : lm32_include.v
// Title : CPU global macros
// Version : 6.1.17
// : Initial Release
// Version : 7.0SP2, 3.0
// : No Change
// Version : 3.1
// : No Change
// Version : 3.2
// : No Change
// Version : 3.3
// : Support for extended configuration register
// =============================================================================
`ifdef LM32_INCLUDE_V
`else
`define LM32_INCLUDE_V
//
// Common configuration options
//
`define CFG_EBA_RESET 32'h0
`define CFG_DEBA_RESET 32'h0
//`define CFG_PL_MULTIPLY_ENABLED
//`define CFG_PL_BARREL_SHIFT_ENABLED
//`define CFG_SIGN_EXTEND_ENABLED
//`define CFG_MC_DIVIDE_ENABLED
//`define CFG_ICACHE_ENABLED
`define CFG_ICACHE_ASSOCIATIVITY 2
`define CFG_ICACHE_SETS 256
`define CFG_ICACHE_BYTES_PER_LINE 16
`define CFG_ICACHE_BASE_ADDRESS 32'h0
`define CFG_ICACHE_LIMIT 32'h7fffffff
//`define CFG_DCACHE_ENABLED
`define CFG_DCACHE_ASSOCIATIVITY 2
`define CFG_DCACHE_SETS 512
`define CFG_DCACHE_BYTES_PER_LINE 16
`define CFG_DCACHE_BASE_ADDRESS 32'h0
`define CFG_DCACHE_LIMIT 32'h7fffffff
//
// End of common configuration options
//
`ifdef TRUE
`else
`define TRUE 1'b1
`define FALSE 1'b0
`define TRUE_N 1'b0
`define FALSE_N 1'b1
`endif
// Wishbone configuration
`define CFG_IWB_ENABLED
`define CFG_DWB_ENABLED
// Data-path width
`define LM32_WORD_WIDTH 32
`define LM32_WORD_RNG (`LM32_WORD_WIDTH-1):0
`define LM32_SHIFT_WIDTH 5
`define LM32_SHIFT_RNG (`LM32_SHIFT_WIDTH-1):0
`define LM32_BYTE_SELECT_WIDTH 4
`define LM32_BYTE_SELECT_RNG (`LM32_BYTE_SELECT_WIDTH-1):0
// Register file size
`define LM32_REGISTERS 32
`define LM32_REG_IDX_WIDTH 5
`define LM32_REG_IDX_RNG (`LM32_REG_IDX_WIDTH-1):0
// Standard register numbers
`define LM32_RA_REG `LM32_REG_IDX_WIDTH'd29
`define LM32_EA_REG `LM32_REG_IDX_WIDTH'd30
`define LM32_BA_REG `LM32_REG_IDX_WIDTH'd31
// Range of Program Counter. Two LSBs are always 0.
// `ifdef CFG_ICACHE_ENABLED
// `define LM32_PC_WIDTH (clogb2(`CFG_ICACHE_LIMIT-`CFG_ICACHE_BASE_ADDRESS)-2)
// `else
// `ifdef CFG_IWB_ENABLED
`define LM32_PC_WIDTH (`LM32_WORD_WIDTH-2)
// `else
// `define LM32_PC_WIDTH `LM32_IROM_ADDRESS_WIDTH
// `endif
// `endif
`define LM32_PC_RNG (`LM32_PC_WIDTH+2-1):2
// Range of an instruction
`define LM32_INSTRUCTION_WIDTH 32
`define LM32_INSTRUCTION_RNG (`LM32_INSTRUCTION_WIDTH-1):0
// Adder operation
`define LM32_ADDER_OP_ADD 1'b0
`define LM32_ADDER_OP_SUBTRACT 1'b1
// Shift direction
`define LM32_SHIFT_OP_RIGHT 1'b0
`define LM32_SHIFT_OP_LEFT 1'b1
// Currently always enabled
`define CFG_BUS_ERRORS_ENABLED
// Derive macro that indicates whether we have single-stepping or not
`ifdef CFG_ROM_DEBUG_ENABLED
`define LM32_SINGLE_STEP_ENABLED
`else
`ifdef CFG_HW_DEBUG_ENABLED
`define LM32_SINGLE_STEP_ENABLED
`endif
`endif
// Derive macro that indicates whether JTAG interface is required
`ifdef CFG_JTAG_UART_ENABLED
`define LM32_JTAG_ENABLED
`else
`ifdef CFG_DEBUG_ENABLED
`define LM32_JTAG_ENABLED
`else
`endif
`endif
// Derive macro that indicates whether we have a barrel-shifter or not
`ifdef CFG_PL_BARREL_SHIFT_ENABLED
`define LM32_BARREL_SHIFT_ENABLED
`else // CFG_PL_BARREL_SHIFT_ENABLED
`ifdef CFG_MC_BARREL_SHIFT_ENABLED
`define LM32_BARREL_SHIFT_ENABLED
`else
`define LM32_NO_BARREL_SHIFT
`endif
`endif // CFG_PL_BARREL_SHIFT_ENABLED
// Derive macro that indicates whether we have a multiplier or not
`ifdef CFG_PL_MULTIPLY_ENABLED
`define LM32_MULTIPLY_ENABLED
`else
`ifdef CFG_MC_MULTIPLY_ENABLED
`define LM32_MULTIPLY_ENABLED
`endif
`endif
// Derive a macro that indicates whether or not the multi-cycle arithmetic unit is required
`ifdef CFG_MC_DIVIDE_ENABLED
`define LM32_MC_ARITHMETIC_ENABLED
`endif
`ifdef CFG_MC_MULTIPLY_ENABLED
`define LM32_MC_ARITHMETIC_ENABLED
`endif
`ifdef CFG_MC_BARREL_SHIFT_ENABLED
`define LM32_MC_ARITHMETIC_ENABLED
`endif
// Derive macro that indicates if we are using an EBR register file
`ifdef CFG_EBR_POSEDGE_REGISTER_FILE
`define LM32_EBR_REGISTER_FILE
`endif
`ifdef CFG_EBR_NEGEDGE_REGISTER_FILE
`define LM32_EBR_REGISTER_FILE
`endif
// Revision number
`define LM32_REVISION 6'h02
// Logical operations - Function encoded directly in instruction
`define LM32_LOGIC_OP_RNG 3:0
// Conditions for conditional branches
`define LM32_CONDITION_WIDTH 3
`define LM32_CONDITION_RNG (`LM32_CONDITION_WIDTH-1):0
`define LM32_CONDITION_E 3'b001
`define LM32_CONDITION_G 3'b010
`define LM32_CONDITION_GE 3'b011
`define LM32_CONDITION_GEU 3'b100
`define LM32_CONDITION_GU 3'b101
`define LM32_CONDITION_NE 3'b111
`define LM32_CONDITION_U1 3'b000
`define LM32_CONDITION_U2 3'b110
// Size of load or store instruction - Encoding corresponds to opcode
`define LM32_SIZE_WIDTH 2
`define LM32_SIZE_RNG 1:0
`define LM32_SIZE_BYTE 2'b00
`define LM32_SIZE_HWORD 2'b11
`define LM32_SIZE_WORD 2'b10
`define LM32_ADDRESS_LSBS_WIDTH 2
// Width and range of a CSR index
`ifdef CFG_DEBUG_ENABLED
`define LM32_CSR_WIDTH 5
`define LM32_CSR_RNG (`LM32_CSR_WIDTH-1):0
`else
`ifdef CFG_JTAG_ENABLED
`define LM32_CSR_WIDTH 4
`define LM32_CSR_RNG (`LM32_CSR_WIDTH-1):0
`else
`define LM32_CSR_WIDTH 3
`define LM32_CSR_RNG (`LM32_CSR_WIDTH-1):0
`endif
`endif
// CSR indices
`define LM32_CSR_IE `LM32_CSR_WIDTH'h0
`define LM32_CSR_IM `LM32_CSR_WIDTH'h1
`define LM32_CSR_IP `LM32_CSR_WIDTH'h2
`define LM32_CSR_ICC `LM32_CSR_WIDTH'h3
`define LM32_CSR_DCC `LM32_CSR_WIDTH'h4
`define LM32_CSR_CC `LM32_CSR_WIDTH'h5
`define LM32_CSR_CFG `LM32_CSR_WIDTH'h6
`define LM32_CSR_EBA `LM32_CSR_WIDTH'h7
`ifdef CFG_DEBUG_ENABLED
`define LM32_CSR_DC `LM32_CSR_WIDTH'h8
`define LM32_CSR_DEBA `LM32_CSR_WIDTH'h9
`endif
`define LM32_CSR_CFG2 `LM32_CSR_WIDTH'ha
`ifdef CFG_JTAG_ENABLED
`define LM32_CSR_JTX `LM32_CSR_WIDTH'he
`define LM32_CSR_JRX `LM32_CSR_WIDTH'hf
`endif
`ifdef CFG_DEBUG_ENABLED
`define LM32_CSR_BP0 `LM32_CSR_WIDTH'h10
`define LM32_CSR_BP1 `LM32_CSR_WIDTH'h11
`define LM32_CSR_BP2 `LM32_CSR_WIDTH'h12
`define LM32_CSR_BP3 `LM32_CSR_WIDTH'h13
`define LM32_CSR_WP0 `LM32_CSR_WIDTH'h18
`define LM32_CSR_WP1 `LM32_CSR_WIDTH'h19
`define LM32_CSR_WP2 `LM32_CSR_WIDTH'h1a
`define LM32_CSR_WP3 `LM32_CSR_WIDTH'h1b
`endif
// Values for WPC CSR
`define LM32_WPC_C_RNG 1:0
`define LM32_WPC_C_DISABLED 2'b00
`define LM32_WPC_C_READ 2'b01
`define LM32_WPC_C_WRITE 2'b10
`define LM32_WPC_C_READ_WRITE 2'b11
// Exception IDs
`define LM32_EID_WIDTH 3
`define LM32_EID_RNG (`LM32_EID_WIDTH-1):0
`define LM32_EID_RESET 3'h0
`define LM32_EID_BREAKPOINT 3'd1
`define LM32_EID_INST_BUS_ERROR 3'h2
`define LM32_EID_WATCHPOINT 3'd3
`define LM32_EID_DATA_BUS_ERROR 3'h4
`define LM32_EID_DIVIDE_BY_ZERO 3'h5
`define LM32_EID_INTERRUPT 3'h6
`define LM32_EID_SCALL 3'h7
// Pipeline result selection mux controls
`define LM32_D_RESULT_SEL_0_RNG 0:0
`define LM32_D_RESULT_SEL_0_REG_0 1'b0
`define LM32_D_RESULT_SEL_0_NEXT_PC 1'b1
`define LM32_D_RESULT_SEL_1_RNG 1:0
`define LM32_D_RESULT_SEL_1_ZERO 2'b00
`define LM32_D_RESULT_SEL_1_REG_1 2'b01
`define LM32_D_RESULT_SEL_1_IMMEDIATE 2'b10
`define LM32_USER_OPCODE_WIDTH 11
`define LM32_USER_OPCODE_RNG (`LM32_USER_OPCODE_WIDTH-1):0
// Derive a macro to indicate if either of the caches are implemented
`ifdef CFG_ICACHE_ENABLED
`define LM32_CACHE_ENABLED
`else
`ifdef CFG_DCACHE_ENABLED
`define LM32_CACHE_ENABLED
`endif
`endif
/////////////////////////////////////////////////////
// Interrupts
/////////////////////////////////////////////////////
// Always enable interrupts
`define CFG_INTERRUPTS_ENABLED
// Currently this is fixed to 32 and should not be changed
`define CFG_INTERRUPTS 32
`define LM32_INTERRUPT_WIDTH `CFG_INTERRUPTS
`define LM32_INTERRUPT_RNG (`LM32_INTERRUPT_WIDTH-1):0
/////////////////////////////////////////////////////
// General
/////////////////////////////////////////////////////
// Sub-word range types
`define LM32_BYTE_WIDTH 8
`define LM32_BYTE_RNG 7:0
`define LM32_HWORD_WIDTH 16
`define LM32_HWORD_RNG 15:0
// Word sub-byte indicies
`define LM32_BYTE_0_RNG 7:0
`define LM32_BYTE_1_RNG 15:8
`define LM32_BYTE_2_RNG 23:16
`define LM32_BYTE_3_RNG 31:24
// Word sub-halfword indices
`define LM32_HWORD_0_RNG 15:0
`define LM32_HWORD_1_RNG 31:16
// Use a synchronous reset
`define CFG_RESET_SENSITIVITY
// V.T. Srce
`define SRCE
// Whether to include context registers for debug exceptions
// in addition to standard exception handling registers
// Bizarre - Removing this increases LUT count!
`define CFG_DEBUG_EXCEPTIONS_ENABLED
// Wishbone defines
// Refer to Wishbone System-on-Chip Interconnection Architecture
// These should probably be moved to a Wishbone common file
// Wishbone cycle types
`define LM32_CTYPE_WIDTH 3
`define LM32_CTYPE_RNG (`LM32_CTYPE_WIDTH-1):0
`define LM32_CTYPE_CLASSIC 3'b000
`define LM32_CTYPE_CONSTANT 3'b001
`define LM32_CTYPE_INCREMENTING 3'b010
`define LM32_CTYPE_END 3'b111
// Wishbone burst types
`define LM32_BTYPE_WIDTH 2
`define LM32_BTYPE_RNG (`LM32_BTYPE_WIDTH-1):0
`define LM32_BTYPE_LINEAR 2'b00
`define LM32_BTYPE_4_BEAT 2'b01
`define LM32_BTYPE_8_BEAT 2'b10
`define LM32_BTYPE_16_BEAT 2'b11
`endif
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/rtl/setup.v 0000664 0000000 0000000 00000001647 11632347016 0025724 0 ustar 00root root 0000000 0000000 /*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009, 2011 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* System clock frequency in Hz.
*/
`define CLOCK_FREQUENCY 125000000
/*
* System clock period in ns (must be in sync with CLOCK_FREQUENCY).
*/
`define CLOCK_PERIOD 8
/*
* Default baudrate for the debug UART.
*/
`define BAUD_RATE 115200
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/rtl/system.v 0000664 0000000 0000000 00000023263 11632347016 0026106 0 ustar 00root root 0000000 0000000 /*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
* Copyright (C) 2011 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
`include "setup.v"
module system(
input clkin,
input resetin,
// UART
input uart_rxd,
output uart_txd,
// GPIO
input [2:0] btn,
output [1:0] led,
// TDC
input [1:0] tdc_signal,
input [1:0] tdc_calib
);
//------------------------------------------------------------------
// Clock and Reset Generation
//------------------------------------------------------------------
wire sys_clk;
wire hard_reset;
assign sys_clk = clkin;
`ifndef SIMULATION
/* Synchronize the reset input */
reg rst0;
reg rst1;
always @(posedge sys_clk) rst0 <= resetin;
always @(posedge sys_clk) rst1 <= rst0;
/* Debounce it
* and generate power-on reset.
*/
reg [19:0] rst_debounce;
reg sys_rst;
initial rst_debounce <= 20'hFFFFF;
initial sys_rst <= 1'b1;
always @(posedge sys_clk) begin
if(rst1 | hard_reset)
rst_debounce <= 20'hFFFFF;
else if(rst_debounce != 20'd0)
rst_debounce <= rst_debounce - 20'd1;
sys_rst <= rst_debounce != 20'd0;
end
`else
wire sys_rst;
assign sys_rst = resetin;
`endif
//------------------------------------------------------------------
// Wishbone master wires
//------------------------------------------------------------------
wire [31:0] cpuibus_adr,
cpudbus_adr;
wire [2:0] cpuibus_cti,
cpudbus_cti;
wire [31:0] cpuibus_dat_r,
cpudbus_dat_r,
cpudbus_dat_w;
wire [3:0] cpudbus_sel;
wire cpudbus_we;
wire cpuibus_cyc,
cpudbus_cyc;
wire cpuibus_stb,
cpudbus_stb;
wire cpuibus_ack,
cpudbus_ack;
//------------------------------------------------------------------
// Wishbone slave wires
//------------------------------------------------------------------
wire [31:0] brg_adr,
bram_adr,
sram_adr,
csrbrg_adr,
tdc_adr;
wire [2:0] brg_cti,
bram_cti,
sram_cti;
wire [31:0] bram_dat_r,
sram_dat_r,
sram_dat_w,
csrbrg_dat_r,
csrbrg_dat_w,
tdc_dat_r,
tdc_dat_w;
wire [3:0] bram_sel,
sram_sel,
tdc_sel;
wire csrbrg_we,
sram_we,
tdc_we;
wire bram_cyc,
sram_cyc,
csrbrg_cyc,
tdc_cyc;
wire bram_stb,
sram_stb,
csrbrg_stb,
tdc_stb;
wire bram_ack,
sram_ack,
csrbrg_ack,
tdc_ack;
//---------------------------------------------------------------------------
// Wishbone switch
//---------------------------------------------------------------------------
conbus #(
.s_addr_w(3),
.s0_addr(3'b000), // bram 0x00000000
.s1_addr(3'b001), // free 0x20000000
.s2_addr(3'b010), // sram 0x40000000
.s3_addr(3'b100), // CSR bridge 0x80000000
.s4_addr(3'b101), // TDC 0xa0000000
.s5_addr(3'b110), // free 0xc0000000
) conbus (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
// Master 0
.m0_dat_i(32'hx),
.m0_dat_o(cpuibus_dat_r),
.m0_adr_i(cpuibus_adr),
.m0_cti_i(cpuibus_cti),
.m0_we_i(1'b0),
.m0_sel_i(4'hf),
.m0_cyc_i(cpuibus_cyc),
.m0_stb_i(cpuibus_stb),
.m0_ack_o(cpuibus_ack),
// Master 1
.m1_dat_i(cpudbus_dat_w),
.m1_dat_o(cpudbus_dat_r),
.m1_adr_i(cpudbus_adr),
.m1_cti_i(cpudbus_cti),
.m1_we_i(cpudbus_we),
.m1_sel_i(cpudbus_sel),
.m1_cyc_i(cpudbus_cyc),
.m1_stb_i(cpudbus_stb),
.m1_ack_o(cpudbus_ack),
// Master 2
.m2_dat_i(32'bx),
.m2_dat_o(),
.m2_adr_i(32'bx),
.m2_cti_i(3'bx),
.m2_we_i(1'bx),
.m2_sel_i(4'bx),
.m2_cyc_i(1'b0),
.m2_stb_i(1'b0),
.m2_ack_o(),
// Master 3
.m3_dat_i(32'bx),
.m3_dat_o(),
.m3_adr_i(32'bx),
.m3_cti_i(3'bx),
.m3_we_i(1'bx),
.m3_sel_i(4'bx),
.m3_cyc_i(1'b0),
.m3_stb_i(1'b0),
.m3_ack_o(),
// Master 4
.m4_dat_i(32'bx),
.m4_dat_o(),
.m4_adr_i(32'bx),
.m4_cti_i(3'bx),
.m4_we_i(1'bx),
.m4_sel_i(4'bx),
.m4_cyc_i(1'b0),
.m4_stb_i(1'b0),
.m4_ack_o(),
// Master 5
.m5_dat_i(32'bx),
.m5_dat_o(),
.m5_adr_i(32'bx),
.m5_cti_i(3'bx),
.m5_we_i(1'bx),
.m5_sel_i(4'bx),
.m5_cyc_i(1'b0),
.m5_stb_i(1'b0),
.m5_ack_o(),
// Slave 0
.s0_dat_i(bram_dat_r),
.s0_dat_o(),
.s0_adr_o(bram_adr),
.s0_cti_o(bram_cti),
.s0_sel_o(bram_sel),
.s0_we_o(),
.s0_cyc_o(bram_cyc),
.s0_stb_o(bram_stb),
.s0_ack_i(bram_ack),
// Slave 1
.s1_dat_i(32'bx),
.s1_adr_o(),
.s1_cyc_o(),
.s1_stb_o(),
.s1_ack_i(1'b0),
// Slave 2
.s2_dat_i(sram_dat_r),
.s2_dat_o(sram_dat_w),
.s2_adr_o(sram_adr),
.s2_cti_o(sram_cti),
.s2_sel_o(sram_sel),
.s2_we_o(sram_we),
.s2_cyc_o(sram_cyc),
.s2_stb_o(sram_stb),
.s2_ack_i(sram_ack),
// Slave 3
.s3_dat_i(csrbrg_dat_r),
.s3_dat_o(csrbrg_dat_w),
.s3_adr_o(csrbrg_adr),
.s3_we_o(csrbrg_we),
.s3_cyc_o(csrbrg_cyc),
.s3_stb_o(csrbrg_stb),
.s3_ack_i(csrbrg_ack),
// Slave 4
.s4_dat_i(tdc_dat_r),
.s4_dat_o(tdc_dat_w),
.s4_adr_o(tdc_adr),
.s4_we_o(tdc_we),
.s4_cyc_o(tdc_cyc),
.s4_stb_o(tdc_stb),
.s4_sel_o(tdc_sel),
.s4_ack_i(tdc_ack),
// Slave 5
.s5_dat_i(32'bx),
.s5_adr_o(),
.s5_cyc_o(),
.s5_stb_o(),
.s5_ack_i(1'b0)
);
//------------------------------------------------------------------
// CSR bus
//------------------------------------------------------------------
wire [13:0] csr_a;
wire csr_we;
wire [31:0] csr_dw;
wire [31:0] csr_dr_uart,
csr_dr_sysctl;
//---------------------------------------------------------------------------
// WISHBONE to CSR bridge
//---------------------------------------------------------------------------
csrbrg csrbrg(
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.wb_adr_i(csrbrg_adr),
.wb_dat_i(csrbrg_dat_w),
.wb_dat_o(csrbrg_dat_r),
.wb_cyc_i(csrbrg_cyc),
.wb_stb_i(csrbrg_stb),
.wb_we_i(csrbrg_we),
.wb_ack_o(csrbrg_ack),
.csr_a(csr_a),
.csr_we(csr_we),
.csr_do(csr_dw),
/* combine all slave->master data lines with an OR */
.csr_di(
csr_dr_uart
|csr_dr_sysctl
)
);
//---------------------------------------------------------------------------
// Interrupts
//---------------------------------------------------------------------------
wire gpio_irq;
wire timer0_irq;
wire timer1_irq;
wire uartrx_irq;
wire uarttx_irq;
wire tdc_irq;
wire [31:0] cpu_interrupt;
assign cpu_interrupt = {26'd0,
tdc_irq,
uarttx_irq,
uartrx_irq,
timer1_irq,
timer0_irq,
gpio_irq
};
//---------------------------------------------------------------------------
// LM32 CPU
//---------------------------------------------------------------------------
lm32_top cpu(
.clk_i(sys_clk),
.rst_i(sys_rst),
.interrupt(cpu_interrupt),
.I_ADR_O(cpuibus_adr),
.I_DAT_I(cpuibus_dat_r),
.I_DAT_O(),
.I_SEL_O(),
.I_CYC_O(cpuibus_cyc),
.I_STB_O(cpuibus_stb),
.I_ACK_I(cpuibus_ack),
.I_WE_O(),
.I_CTI_O(cpuibus_cti),
.I_LOCK_O(),
.I_BTE_O(),
.I_ERR_I(1'b0),
.I_RTY_I(1'b0),
.D_ADR_O(cpudbus_adr),
.D_DAT_I(cpudbus_dat_r),
.D_DAT_O(cpudbus_dat_w),
.D_SEL_O(cpudbus_sel),
.D_CYC_O(cpudbus_cyc),
.D_STB_O(cpudbus_stb),
.D_ACK_I(cpudbus_ack),
.D_WE_O (cpudbus_we),
.D_CTI_O(cpudbus_cti),
.D_LOCK_O(),
.D_BTE_O(),
.D_ERR_I(1'b0),
.D_RTY_I(1'b0)
);
//---------------------------------------------------------------------------
// BRAM/SRAM
//---------------------------------------------------------------------------
bram #(
.adr_width(14),
.init0("../../../software/bios/bios.h1"),
.init1("../../../software/bios/bios.h2"),
.init2("../../../software/bios/bios.h3"),
.init3("../../../software/bios/bios.h4")
) bram (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.wb_adr_i(bram_adr),
.wb_dat_o(bram_dat_r),
.wb_dat_i(32'bx),
.wb_sel_i(bram_sel),
.wb_stb_i(bram_stb),
.wb_cyc_i(bram_cyc),
.wb_ack_o(bram_ack),
.wb_we_i(1'b0)
);
bram #(
.adr_width(14)
) sram (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.wb_adr_i(sram_adr),
.wb_dat_o(sram_dat_r),
.wb_dat_i(sram_dat_w),
.wb_sel_i(sram_sel),
.wb_stb_i(sram_stb),
.wb_cyc_i(sram_cyc),
.wb_ack_o(sram_ack),
.wb_we_i(sram_we)
);
//---------------------------------------------------------------------------
// UART
//---------------------------------------------------------------------------
uart #(
.csr_addr(4'h0),
.clk_freq(`CLOCK_FREQUENCY),
.baud(`BAUD_RATE)
) uart (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.csr_a(csr_a),
.csr_we(csr_we),
.csr_di(csr_dw),
.csr_do(csr_dr_uart),
.rx_irq(uartrx_irq),
.tx_irq(uarttx_irq),
.uart_rxd(uart_rxd),
.uart_txd(uart_txd)
);
//---------------------------------------------------------------------------
// System Controller
//---------------------------------------------------------------------------
sysctl #(
.csr_addr(4'h1),
.ninputs(3),
.noutputs(2),
.systemid(32'h53504543) /* SPEC */
) sysctl (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.gpio_irq(gpio_irq),
.timer0_irq(timer0_irq),
.timer1_irq(timer1_irq),
.csr_a(csr_a),
.csr_we(csr_we),
.csr_di(csr_dw),
.csr_do(csr_dr_sysctl),
.gpio_inputs(btn),
.gpio_outputs(led),
.hard_reset(hard_reset)
);
//---------------------------------------------------------------------------
// TDC
//---------------------------------------------------------------------------
tdc_hostif #(
.g_CHANNEL_COUNT(2),
.g_CARRY4_COUNT(100),
.g_RAW_COUNT(9),
.g_FP_COUNT(13),
.g_COARSE_COUNT(25),
.g_RO_LENGTH(20),
.g_FCOUNTER_WIDTH(13),
.g_FTIMER_WIDTH(10)
) tdc (
.rst_n_i(~sys_rst),
.wb_clk_i(sys_clk),
.wb_addr_i(tdc_adr[5:0]),
.wb_data_i(tdc_dat_w),
.wb_data_o(tdc_dat_r),
.wb_cyc_i(tdc_cyc),
.wb_sel_i(tdc_sel),
.wb_stb_i(tdc_stb),
.wb_we_i(tdc_we),
.wb_ack_o(tdc_ack),
.wb_irq_o(tdc_irq),
.cc_rst_i(1'b0),
.cc_cy_o(),
.signal_i(tdc_signal),
.calib_i(tdc_calib)
);
endmodule
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/sources.mak 0000664 0000000 0000000 00000002150 11632347016 0025737 0 ustar 00root root 0000000 0000000 BOARD_SRC=$(wildcard $(BOARD_DIR)/*.v)
CONBUS_SRC=$(wildcard $(CORES_DIR)/conbus/rtl/*.v)
LM32_SRC= \
$(CORES_DIR)/lm32/rtl/lm32_cpu.v \
$(CORES_DIR)/lm32/rtl/lm32_instruction_unit.v \
$(CORES_DIR)/lm32/rtl/lm32_decoder.v \
$(CORES_DIR)/lm32/rtl/lm32_load_store_unit.v \
$(CORES_DIR)/lm32/rtl/lm32_adder.v \
$(CORES_DIR)/lm32/rtl/lm32_addsub.v \
$(CORES_DIR)/lm32/rtl/lm32_logic_op.v \
$(CORES_DIR)/lm32/rtl/lm32_shifter.v \
$(CORES_DIR)/lm32/rtl/lm32_interrupt.v \
$(CORES_DIR)/lm32/rtl/lm32_top.v
CSRBRG_SRC=$(wildcard $(CORES_DIR)/csrbrg/rtl/*.v)
BRAM_SRC=$(wildcard $(CORES_DIR)/bram/rtl/*.v)
UART_SRC=$(wildcard $(CORES_DIR)/uart/rtl/*.v)
SYSCTL_SRC=$(wildcard $(CORES_DIR)/sysctl/rtl/*.v)
CORES_SRC=$(CONBUS_SRC) $(LM32_SRC) $(CSRBRG_SRC) $(BRAM_SRC) $(UART_SRC) $(SYSCTL_SRC)
TDC_SRC=$(wildcard $(TDC_DIR)/core/*.vhd)
TDCHI_SRC=$(wildcard $(TDC_DIR)/hostif/*.vhd)
GENRAMS_SRC=$(wildcard $(GENCORES_DIR)/modules/genrams/*.vhd) $(wildcard $(GENCORES_DIR)/modules/genrams/xilinx/*.vhd)
WBGEN_SRC=$(wildcard $(WBGEN_DIR)/lib/*.vhd)
CORES_SRC_VHDL=$(GENRAMS_SRC) $(WBGEN_SRC) $(TDC_SRC) $(TDCHI_SRC)
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/synthesis/ 0000775 0000000 0000000 00000000000 11632347016 0025615 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/synthesis/Makefile.xst 0000664 0000000 0000000 00000001370 11632347016 0030073 0 ustar 00root root 0000000 0000000 BOARD_DIR=../rtl
CORES_DIR=../../../cores
GENCORES_DIR=../../../../../general-cores
WBGEN_DIR=../../../../../wishbone-gen
TDC_DIR=../../../..
include ../sources.mak
SRC=$(BOARD_SRC) $(CORES_SRC)
SRC_VHDL=$(CORES_SRC_VHDL)
all: build/system.bit
build/system.ucf: common.ucf xst.ucf
cat common.ucf xst.ucf > build/system.ucf
build/system.prj: $(SRC) $(SRC_VHDL)
rm -f build/system.prj
for i in `echo $(SRC)`; do \
echo "verilog work ../$$i" >> build/system.prj; \
done
for i in `echo $(SRC_VHDL)`; do \
echo "vhdl work ../$$i" >> build/system.prj; \
done
build/system.ngc: build/system.prj
cd build && xst -ifn ../system.xst
build/system.ngd: build/system.ngc build/system.ucf
cd build && ngdbuild -uc system.ucf system.ngc
include common.mak
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/synthesis/build/ 0000775 0000000 0000000 00000000000 11632347016 0026714 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/synthesis/build/.keep_me 0000664 0000000 0000000 00000000000 11632347016 0030310 0 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/synthesis/common.mak 0000664 0000000 0000000 00000001017 11632347016 0027576 0 ustar 00root root 0000000 0000000 timing: build/system-routed.twr
load: build/system.bit
cd build && impact -batch ../load.cmd
build/system.ncd: build/system.ngd
cd build && map -ol high -w system.ngd
build/system-routed.ncd: build/system.ncd
cd build && par -ol high -w system.ncd system-routed.ncd
build/system.bit: build/system-routed.ncd
cd build && bitgen -w system-routed.ncd system.bit
build/system-routed.twr: build/system-routed.ncd
cd build && trce -v 10 system-routed.ncd system.pcf
clean:
rm -rf build/*
.PHONY: timing usage load clean
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/synthesis/common.ucf 0000664 0000000 0000000 00000000410 11632347016 0027577 0 ustar 00root root 0000000 0000000 # ==== Clock input ====
NET "clkin" TNM_NET = CLK_125MHZ;
TIMESPEC TS_CLK_125MHZ = PERIOD CLK_125MHZ 8 ns;
NET "tdc/cmp_tdc/cmp_channelbank/g_channels[0].cmp_channel/muxed_signal" TIG;
NET "tdc/cmp_tdc/cmp_channelbank/g_channels[1].cmp_channel/muxed_signal" TIG;
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/synthesis/load.cmd 0000664 0000000 0000000 00000000134 11632347016 0027217 0 ustar 00root root 0000000 0000000 setMode -bscan
setCable -p auto
identify
assignfile -p 1 -file system.bit
program -p 1
quit
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/synthesis/system.xst 0000664 0000000 0000000 00000000157 11632347016 0027704 0 ustar 00root root 0000000 0000000 run
-ifn system.prj
-top system
-ifmt MIXED
-opt_mode SPEED
-opt_level 2
-ofn system.ngc
-p xc6slx45t-fgg484-2
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/boards/spec/synthesis/xst.ucf 0000664 0000000 0000000 00000000000 11632347016 0027120 0 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/ 0000775 0000000 0000000 00000000000 11632347016 0022473 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/bram/ 0000775 0000000 0000000 00000000000 11632347016 0023414 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/bram/doc/ 0000775 0000000 0000000 00000000000 11632347016 0024161 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/bram/doc/Makefile 0000664 0000000 0000000 00000000411 11632347016 0025615 0 ustar 00root root 0000000 0000000 TEX=bram.tex
DVI=$(TEX:.tex=.dvi)
PS=$(TEX:.tex=.ps)
PDF=$(TEX:.tex=.pdf)
AUX=$(TEX:.tex=.aux)
LOG=$(TEX:.tex=.log)
all: $(PDF)
%.dvi: %.tex
latex $<
%.ps: %.dvi
dvips $<
%.pdf: %.ps
ps2pdf $<
clean:
rm -f $(DVI) $(PS) $(PDF) $(AUX) $(LOG)
.PHONY: clean
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/bram/doc/bram.tex 0000664 0000000 0000000 00000002361 11632347016 0025626 0 ustar 00root root 0000000 0000000 \documentclass[a4paper,11pt]{article}
\usepackage{fullpage}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[normalem]{ulem}
\usepackage[english]{babel}
\usepackage{listings,babel}
\lstset{breaklines=true,basicstyle=\ttfamily}
\usepackage{graphicx}
\usepackage{moreverb}
\usepackage{url}
\title{Wishbone Block RAM}
\author{S\'ebastien Bourdeauducq}
\date{December 2009}
\begin{document}
\setlength{\parindent}{0pt}
\setlength{\parskip}{5pt}
\maketitle{}
\section{Specifications}
This core creates 32-bit storage RAM on the Wishbone bus by using FPGA Block RAM.
Byte-wide writes are supported. Burst access is not supported.
The typical use case is to provide initial memory for softcore CPUs.
\section{Using the core}
You should specify the block RAM storage depth, in bytes, by using the \verb!adr_width! parameter.
\section*{Copyright notice}
Copyright \copyright 2007-2009 S\'ebastien Bourdeauducq. \\
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the LICENSE.FDL file at the root of the Milkymist source distribution.
\end{document}
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/bram/rtl/ 0000775 0000000 0000000 00000000000 11632347016 0024215 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/bram/rtl/bram.v 0000664 0000000 0000000 00000005735 11632347016 0025337 0 ustar 00root root 0000000 0000000 /*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
* Copyright (C) 2011 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
module bram #(
parameter adr_width = 11, // in bytes
parameter init0 = "",
parameter init1 = "",
parameter init2 = "",
parameter init3 = ""
) (
input sys_clk,
input sys_rst,
input wb_stb_i,
input wb_cyc_i,
input wb_we_i,
output reg wb_ack_o,
input [31:0] wb_adr_i,
output [31:0] wb_dat_o,
input [31:0] wb_dat_i,
input [3:0] wb_sel_i
);
//-----------------------------------------------------------------
// Storage depth in 32 bit words
//-----------------------------------------------------------------
parameter word_width = adr_width - 2;
parameter word_depth = (1 << word_width);
//-----------------------------------------------------------------
// Actual RAM
//-----------------------------------------------------------------
reg [7:0] ram0 [0:word_depth-1];
reg [7:0] ram1 [0:word_depth-1];
reg [7:0] ram2 [0:word_depth-1];
reg [7:0] ram3 [0:word_depth-1];
initial begin
if(init0 != "")
$readmemh(init0, ram0);
if(init1 != "")
$readmemh(init1, ram1);
if(init2 != "")
$readmemh(init2, ram2);
if(init3 != "")
$readmemh(init3, ram3);
end
wire [word_width-1:0] adr;
wire [7:0] ram0di;
wire ram0we;
wire [7:0] ram1di;
wire ram1we;
wire [7:0] ram2di;
wire ram2we;
wire [7:0] ram3di;
wire ram3we;
reg [7:0] ram0do;
reg [7:0] ram1do;
reg [7:0] ram2do;
reg [7:0] ram3do;
always @(posedge sys_clk) begin
if(ram0we)
ram0[adr] <= ram0di;
ram0do <= ram0[adr];
end
always @(posedge sys_clk) begin
if(ram1we)
ram1[adr] <= ram1di;
ram1do <= ram1[adr];
end
always @(posedge sys_clk) begin
if(ram2we)
ram2[adr] <= ram2di;
ram2do <= ram2[adr];
end
always @(posedge sys_clk) begin
if(ram3we)
ram3[adr] <= ram3di;
ram3do <= ram3[adr];
end
assign ram0we = wb_cyc_i & wb_stb_i & wb_we_i & wb_sel_i[0];
assign ram1we = wb_cyc_i & wb_stb_i & wb_we_i & wb_sel_i[1];
assign ram2we = wb_cyc_i & wb_stb_i & wb_we_i & wb_sel_i[2];
assign ram3we = wb_cyc_i & wb_stb_i & wb_we_i & wb_sel_i[3];
assign ram0di = wb_dat_i[7:0];
assign ram1di = wb_dat_i[15:8];
assign ram2di = wb_dat_i[23:16];
assign ram3di = wb_dat_i[31:24];
assign wb_dat_o = {ram3do, ram2do, ram1do, ram0do};
assign adr = wb_adr_i[adr_width-1:2];
always @(posedge sys_clk) begin
if(sys_rst)
wb_ack_o <= 1'b0;
else begin
if(wb_cyc_i & wb_stb_i)
wb_ack_o <= ~wb_ack_o;
else
wb_ack_o <= 1'b0;
end
end
endmodule
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/ 0000775 0000000 0000000 00000000000 11632347016 0023764 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/doc/ 0000775 0000000 0000000 00000000000 11632347016 0024531 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/doc/Makefile 0000664 0000000 0000000 00000000413 11632347016 0026167 0 ustar 00root root 0000000 0000000 TEX=conbus.tex
DVI=$(TEX:.tex=.dvi)
PS=$(TEX:.tex=.ps)
PDF=$(TEX:.tex=.pdf)
AUX=$(TEX:.tex=.aux)
LOG=$(TEX:.tex=.log)
all: $(PDF)
%.dvi: %.tex
latex $<
%.ps: %.dvi
dvips $<
%.pdf: %.ps
ps2pdf $<
clean:
rm -f $(DVI) $(PS) $(PDF) $(AUX) $(LOG)
.PHONY: clean
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/doc/conbus.tex 0000664 0000000 0000000 00000002666 11632347016 0026556 0 ustar 00root root 0000000 0000000 \documentclass[a4paper,11pt]{article}
\usepackage{fullpage}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[normalem]{ulem}
\usepackage[english]{babel}
\usepackage{listings,babel}
\lstset{breaklines=true,basicstyle=\ttfamily}
\usepackage{graphicx}
\usepackage{moreverb}
\usepackage{url}
\title{Wishbone bus arbiter and address decoder}
\author{S\'ebastien Bourdeauducq}
\date{December 2009}
\begin{document}
\setlength{\parindent}{0pt}
\setlength{\parskip}{5pt}
\maketitle{}
\section{Specifications}
This core allows up to several masters to communicate with up to several slaves on a shared Wishbone bus.
It takes care of bus arbitration and remapping of the slave base addresses. It is very simple and does not take care of priorities. Scheduling occurs when a master releases the bus, and then the next master which requested the bus takes ownership.
It is based on \verb!wb_conbus! from OpenCores.
\section{Using the core}
All parameters and ports should be self-explanatory. No special care should be taken.
\section*{Copyright notice}
Copyright \copyright 2007-2009 S\'ebastien Bourdeauducq. \\
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the LICENSE.FDL file at the root of the Milkymist source distribution.
\end{document}
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/rtl/ 0000775 0000000 0000000 00000000000 11632347016 0024565 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/rtl/conbus.v 0000664 0000000 0000000 00000016345 11632347016 0026256 0 ustar 00root root 0000000 0000000 /*
* Wishbone Arbiter and Address Decoder
* Copyright (C) 2008, 2009, 2010 Sebastien Bourdeauducq
* Copyright (C) 2000 Johny Chi - chisuhua@yahoo.com.cn
* This file is part of Milkymist.
*
* This source file may be used and distributed without
* restriction provided that this copyright statement is not
* removed from the file and that any derivative work contains
* the original copyright notice and the associated disclaimer.
*
* 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.opencores.org/lgpl.shtml.
*/
module conbus #(
parameter s_addr_w = 4,
parameter s0_addr = 4'h0,
parameter s1_addr = 4'h1,
parameter s2_addr = 4'h2,
parameter s3_addr = 4'h3,
parameter s4_addr = 4'h4,
parameter s5_addr = 4'h5
) (
input sys_clk,
input sys_rst,
// Master 0 Interface
input [31:0] m0_dat_i,
output [31:0] m0_dat_o,
input [31:0] m0_adr_i,
input [2:0] m0_cti_i,
input [3:0] m0_sel_i,
input m0_we_i,
input m0_cyc_i,
input m0_stb_i,
output m0_ack_o,
// Master 1 Interface
input [31:0] m1_dat_i,
output [31:0] m1_dat_o,
input [31:0] m1_adr_i,
input [2:0] m1_cti_i,
input [3:0] m1_sel_i,
input m1_we_i,
input m1_cyc_i,
input m1_stb_i,
output m1_ack_o,
// Master 2 Interface
input [31:0] m2_dat_i,
output [31:0] m2_dat_o,
input [31:0] m2_adr_i,
input [2:0] m2_cti_i,
input [3:0] m2_sel_i,
input m2_we_i,
input m2_cyc_i,
input m2_stb_i,
output m2_ack_o,
// Master 3 Interface
input [31:0] m3_dat_i,
output [31:0] m3_dat_o,
input [31:0] m3_adr_i,
input [2:0] m3_cti_i,
input [3:0] m3_sel_i,
input m3_we_i,
input m3_cyc_i,
input m3_stb_i,
output m3_ack_o,
// Master 4 Interface
input [31:0] m4_dat_i,
output [31:0] m4_dat_o,
input [31:0] m4_adr_i,
input [2:0] m4_cti_i,
input [3:0] m4_sel_i,
input m4_we_i,
input m4_cyc_i,
input m4_stb_i,
output m4_ack_o,
// Master 5 Interface
input [31:0] m5_dat_i,
output [31:0] m5_dat_o,
input [31:0] m5_adr_i,
input [2:0] m5_cti_i,
input [3:0] m5_sel_i,
input m5_we_i,
input m5_cyc_i,
input m5_stb_i,
output m5_ack_o,
// Slave 0 Interface
input [31:0] s0_dat_i,
output [31:0] s0_dat_o,
output [31:0] s0_adr_o,
output [2:0] s0_cti_o,
output [3:0] s0_sel_o,
output s0_we_o,
output s0_cyc_o,
output s0_stb_o,
input s0_ack_i,
// Slave 1 Interface
input [31:0] s1_dat_i,
output [31:0] s1_dat_o,
output [31:0] s1_adr_o,
output [2:0] s1_cti_o,
output [3:0] s1_sel_o,
output s1_we_o,
output s1_cyc_o,
output s1_stb_o,
input s1_ack_i,
// Slave 2 Interface
input [31:0] s2_dat_i,
output [31:0] s2_dat_o,
output [31:0] s2_adr_o,
output [2:0] s2_cti_o,
output [3:0] s2_sel_o,
output s2_we_o,
output s2_cyc_o,
output s2_stb_o,
input s2_ack_i,
// Slave 3 Interface
input [31:0] s3_dat_i,
output [31:0] s3_dat_o,
output [31:0] s3_adr_o,
output [2:0] s3_cti_o,
output [3:0] s3_sel_o,
output s3_we_o,
output s3_cyc_o,
output s3_stb_o,
input s3_ack_i,
// Slave 4 Interface
input [31:0] s4_dat_i,
output [31:0] s4_dat_o,
output [31:0] s4_adr_o,
output [2:0] s4_cti_o,
output [3:0] s4_sel_o,
output s4_we_o,
output s4_cyc_o,
output s4_stb_o,
input s4_ack_i,
// Slave 5 Interface
input [31:0] s5_dat_i,
output [31:0] s5_dat_o,
output [31:0] s5_adr_o,
output [2:0] s5_cti_o,
output [3:0] s5_sel_o,
output s5_we_o,
output s5_cyc_o,
output s5_stb_o,
input s5_ack_i
);
// address + CTI + data + byte select
// + cyc + we + stb
`define mbusw_ls 32 + 3 + 32 + 4 + 3
wire [5:0] slave_sel;
wire [5:0] gnt;
wire [`mbusw_ls -1:0] i_bus_m; // internal shared bus, master data and control to slave
wire [31:0] i_dat_s; // internal shared bus, slave data to master
wire i_bus_ack; // internal shared bus, ack signal
// master 0
assign m0_dat_o = i_dat_s;
assign m0_ack_o = i_bus_ack & gnt[0];
// master 1
assign m1_dat_o = i_dat_s;
assign m1_ack_o = i_bus_ack & gnt[1];
// master 2
assign m2_dat_o = i_dat_s;
assign m2_ack_o = i_bus_ack & gnt[2];
// master 3
assign m3_dat_o = i_dat_s;
assign m3_ack_o = i_bus_ack & gnt[3];
// master 4
assign m4_dat_o = i_dat_s;
assign m4_ack_o = i_bus_ack & gnt[4];
// master 5
assign m5_dat_o = i_dat_s;
assign m5_ack_o = i_bus_ack & gnt[5];
assign i_bus_ack = s0_ack_i | s1_ack_i | s2_ack_i | s3_ack_i | s4_ack_i | s5_ack_i;
// slave 0
assign {s0_adr_o, s0_cti_o, s0_sel_o, s0_dat_o, s0_we_o, s0_cyc_o} = i_bus_m[`mbusw_ls -1:1];
assign s0_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[0]; // stb_o = cyc_i & stb_i & slave_sel
// slave 1
assign {s1_adr_o, s1_cti_o, s1_sel_o, s1_dat_o, s1_we_o, s1_cyc_o} = i_bus_m[`mbusw_ls -1:1];
assign s1_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[1];
// slave 2
assign {s2_adr_o, s2_cti_o, s2_sel_o, s2_dat_o, s2_we_o, s2_cyc_o} = i_bus_m[`mbusw_ls -1:1];
assign s2_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[2];
// slave 3
assign {s3_adr_o, s3_cti_o, s3_sel_o, s3_dat_o, s3_we_o, s3_cyc_o} = i_bus_m[`mbusw_ls -1:1];
assign s3_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[3];
// slave 4
assign {s4_adr_o, s4_cti_o, s4_sel_o, s4_dat_o, s4_we_o, s4_cyc_o} = i_bus_m[`mbusw_ls -1:1];
assign s4_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[4];
// slave 5
assign {s5_adr_o, s5_cti_o, s5_sel_o, s5_dat_o, s5_we_o, s5_cyc_o} = i_bus_m[`mbusw_ls -1:1];
assign s5_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[5];
assign i_bus_m =
({`mbusw_ls{gnt[0]}} & {m0_adr_i, m0_cti_i, m0_sel_i, m0_dat_i, m0_we_i, m0_cyc_i, m0_stb_i})
|({`mbusw_ls{gnt[1]}} & {m1_adr_i, m1_cti_i, m1_sel_i, m1_dat_i, m1_we_i, m1_cyc_i, m1_stb_i})
|({`mbusw_ls{gnt[2]}} & {m2_adr_i, m2_cti_i, m2_sel_i, m2_dat_i, m2_we_i, m2_cyc_i, m2_stb_i})
|({`mbusw_ls{gnt[3]}} & {m3_adr_i, m3_cti_i, m3_sel_i, m3_dat_i, m3_we_i, m3_cyc_i, m3_stb_i})
|({`mbusw_ls{gnt[4]}} & {m4_adr_i, m4_cti_i, m4_sel_i, m4_dat_i, m4_we_i, m4_cyc_i, m4_stb_i})
|({`mbusw_ls{gnt[5]}} & {m5_adr_i, m5_cti_i, m5_sel_i, m5_dat_i, m5_we_i, m5_cyc_i, m5_stb_i});
assign i_dat_s =
({32{slave_sel[ 0]}} & s0_dat_i)
|({32{slave_sel[ 1]}} & s1_dat_i)
|({32{slave_sel[ 2]}} & s2_dat_i)
|({32{slave_sel[ 3]}} & s3_dat_i)
|({32{slave_sel[ 4]}} & s4_dat_i)
|({32{slave_sel[ 5]}} & s5_dat_i);
wire [5:0] req = {m5_cyc_i, m4_cyc_i, m3_cyc_i, m2_cyc_i, m1_cyc_i, m0_cyc_i};
conbus_arb conbus_arb(
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.req(req),
.gnt(gnt)
);
assign slave_sel[0] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s0_addr);
assign slave_sel[1] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s1_addr);
assign slave_sel[2] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s2_addr);
assign slave_sel[3] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s3_addr);
assign slave_sel[4] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s4_addr);
assign slave_sel[5] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s5_addr);
endmodule
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/rtl/conbus_arb.v 0000664 0000000 0000000 00000005313 11632347016 0027073 0 ustar 00root root 0000000 0000000 /*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
module conbus_arb(
input sys_clk,
input sys_rst,
input [5:0] req,
output [5:0] gnt
);
parameter [5:0] grant0 = 6'b000001,
grant1 = 6'b000010,
grant2 = 6'b000100,
grant3 = 6'b001000,
grant4 = 6'b010000,
grant5 = 6'b100000;
reg [5:0] state;
reg [5:0] next_state;
assign gnt = state;
always @(posedge sys_clk) begin
if(sys_rst)
state <= grant0;
else
state <= next_state;
end
always @(*) begin
next_state = state;
case(state)
grant0: begin
if(~req[0]) begin
if(req[1]) next_state = grant1;
else if(req[2]) next_state = grant2;
else if(req[3]) next_state = grant3;
else if(req[4]) next_state = grant4;
else if(req[5]) next_state = grant5;
end
end
grant1: begin
if(~req[1]) begin
if(req[2]) next_state = grant2;
else if(req[3]) next_state = grant3;
else if(req[4]) next_state = grant4;
else if(req[5]) next_state = grant5;
else if(req[0]) next_state = grant0;
end
end
grant2: begin
if(~req[2]) begin
if(req[3]) next_state = grant3;
else if(req[4]) next_state = grant4;
else if(req[5]) next_state = grant5;
else if(req[0]) next_state = grant0;
else if(req[1]) next_state = grant1;
end
end
grant3: begin
if(~req[3]) begin
if(req[4]) next_state = grant4;
else if(req[5]) next_state = grant5;
else if(req[0]) next_state = grant0;
else if(req[1]) next_state = grant1;
else if(req[2]) next_state = grant2;
end
end
grant4: begin
if(~req[4]) begin
if(req[5]) next_state = grant5;
else if(req[0]) next_state = grant0;
else if(req[1]) next_state = grant1;
else if(req[2]) next_state = grant2;
else if(req[3]) next_state = grant3;
end
end
grant5: begin
if(~req[5]) begin
if(req[0]) next_state = grant0;
else if(req[1]) next_state = grant1;
else if(req[2]) next_state = grant2;
else if(req[3]) next_state = grant3;
else if(req[4]) next_state = grant4;
end
end
endcase
end
endmodule
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/test/ 0000775 0000000 0000000 00000000000 11632347016 0024743 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/test/Makefile 0000664 0000000 0000000 00000000410 11632347016 0026376 0 ustar 00root root 0000000 0000000 SOURCES=tb_conbus.v master.v slave.v $(wildcard ../rtl/*.v)
all: tb_conbus
sim: tb_conbus
./tb_conbus
cversim: $(SOURCES)
cver $(SOURCES)
clean:
rm -f tb_conbus verilog.log
tb_conbus: $(SOURCES)
iverilog -o tb_conbus $(SOURCES)
.PHONY: clean sim cversim
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/test/master.v 0000664 0000000 0000000 00000003753 11632347016 0026435 0 ustar 00root root 0000000 0000000 /*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
module master #(
parameter id = 0,
parameter nreads = 128,
parameter nwrites = 128,
parameter p = 4
) (
input sys_clk,
input sys_rst,
output reg [31:0] dat_w,
input [31:0] dat_r,
output reg [31:0] adr,
output [2:0] cti,
output reg we,
output reg [3:0] sel,
output cyc,
output stb,
input ack,
output reg tend
);
integer rcounter;
integer wcounter;
reg active;
assign cyc = active;
assign stb = active;
assign cti = 0;
always @(posedge sys_clk) begin
if(sys_rst) begin
dat_w = 0;
adr = 0;
we = 0;
sel = 0;
active = 0;
rcounter = 0;
wcounter = 0;
tend = 0;
end else begin
if(ack) begin
if(~active)
$display("[M%d] Spurious ack", id);
else begin
if(we)
$display("[M%d] Ack W: %x:%x [%x]", id, adr, dat_w, sel);
else
$display("[M%d] Ack R: %x:%x [%x]", id, adr, dat_r, sel);
end
active = 1'b0;
end else if(~active) begin
if(($random % p) == 0) begin
adr = $random;
adr = adr % 5;
adr = (adr << (32-3)) + id;
sel = sel + 1;
active = 1'b1;
if(($random % 2) == 0) begin
/* Read */
we = 1'b0;
rcounter = rcounter + 1;
end else begin
/* Write */
we = 1'b1;
dat_w = ($random << 16) + id;
wcounter = wcounter + 1;
end
end
end
tend = (rcounter >= nreads) && (wcounter >= nwrites);
end
end
endmodule
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/test/slave.v 0000664 0000000 0000000 00000002471 11632347016 0026250 0 ustar 00root root 0000000 0000000 /*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
module slave #(
parameter id = 0,
parameter p = 3
) (
input sys_clk,
input sys_rst,
input [31:0] dat_w,
output reg [31:0] dat_r,
input [31:0] adr,
input [2:0] cti,
input we,
input [3:0] sel,
input cyc,
input stb,
output reg ack
);
always @(posedge sys_clk) begin
if(sys_rst) begin
dat_r = 0;
ack = 0;
end else begin
if(cyc & stb & ~ack) begin
if(($random % p) == 0) begin
ack = 1;
if(~we)
dat_r = ($random << 16) + id;
if(we)
$display("[S%d] Ack W: %x:%x [%x]", id, adr, dat_w, sel);
else
$display("[S%d] Ack R: %x:%x [%x]", id, adr, dat_r, sel);
end
end else
ack = 0;
end
end
endmodule
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/conbus/test/tb_conbus.v 0000664 0000000 0000000 00000016176 11632347016 0027123 0 ustar 00root root 0000000 0000000 /*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
module tb_conbus();
reg sys_rst;
reg sys_clk;
//------------------------------------------------------------------
// Wishbone master wires
//------------------------------------------------------------------
wire [31:0] m0_adr,
m1_adr,
m2_adr,
m3_adr,
m4_adr;
wire [2:0] m0_cti,
m1_cti,
m2_cti,
m3_cti,
m4_cti;
wire [31:0] m0_dat_r,
m0_dat_w,
m1_dat_r,
m1_dat_w,
m2_dat_r,
m2_dat_w,
m3_dat_r,
m3_dat_w,
m4_dat_r,
m4_dat_w;
wire [3:0] m0_sel,
m1_sel,
m2_sel,
m3_sel,
m4_sel;
wire m0_we,
m1_we,
m2_we,
m3_we,
m4_we;
wire m0_cyc,
m1_cyc,
m2_cyc,
m3_cyc,
m4_cyc;
wire m0_stb,
m1_stb,
m2_stb,
m3_stb,
m4_stb;
wire m0_ack,
m1_ack,
m2_ack,
m3_ack,
m4_ack;
//------------------------------------------------------------------
// Wishbone slave wires
//------------------------------------------------------------------
wire [31:0] s0_adr,
s1_adr,
s2_adr,
s3_adr,
s4_adr;
wire [2:0] s0_cti,
s1_cti,
s2_cti,
s3_cti,
s4_cti;
wire [31:0] s0_dat_r,
s0_dat_w,
s1_dat_r,
s1_dat_w,
s2_dat_r,
s2_dat_w,
s3_dat_r,
s3_dat_w,
s4_dat_r,
s4_dat_w;
wire [3:0] s0_sel,
s1_sel,
s2_sel,
s3_sel,
s4_sel;
wire s0_we,
s1_we,
s2_we,
s3_we,
s4_we;
wire s0_cyc,
s1_cyc,
s2_cyc,
s3_cyc,
s4_cyc;
wire s0_stb,
s1_stb,
s2_stb,
s3_stb,
s4_stb;
wire s0_ack,
s1_ack,
s2_ack,
s3_ack,
s4_ack;
//---------------------------------------------------------------------------
// Wishbone switch
//---------------------------------------------------------------------------
conbus #(
.s_addr_w(3),
.s0_addr(3'b000), // 0x00000000
.s1_addr(3'b001), // 0x20000000
.s2_addr(3'b010), // 0x40000000
.s3_addr(3'b011), // 0x60000000
.s4_addr(3'b100) // 0x80000000
) dut (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
// Master 0
.m0_dat_i(m0_dat_w),
.m0_dat_o(m0_dat_r),
.m0_adr_i(m0_adr),
.m0_cti_i(m0_cti),
.m0_we_i(m0_we),
.m0_sel_i(m0_sel),
.m0_cyc_i(m0_cyc),
.m0_stb_i(m0_stb),
.m0_ack_o(m0_ack),
// Master 1
.m1_dat_i(m1_dat_w),
.m1_dat_o(m1_dat_r),
.m1_adr_i(m1_adr),
.m1_cti_i(m1_cti),
.m1_we_i(m1_we),
.m1_sel_i(m1_sel),
.m1_cyc_i(m1_cyc),
.m1_stb_i(m1_stb),
.m1_ack_o(m1_ack),
// Master 2
.m2_dat_i(m2_dat_w),
.m2_dat_o(m2_dat_r),
.m2_adr_i(m2_adr),
.m2_cti_i(m2_cti),
.m2_we_i(m2_we),
.m2_sel_i(m2_sel),
.m2_cyc_i(m2_cyc),
.m2_stb_i(m2_stb),
.m2_ack_o(m2_ack),
// Master 3
.m3_dat_i(m3_dat_w),
.m3_dat_o(m3_dat_r),
.m3_adr_i(m3_adr),
.m3_cti_i(m3_cti),
.m3_we_i(m3_we),
.m3_sel_i(m3_sel),
.m3_cyc_i(m3_cyc),
.m3_stb_i(m3_stb),
.m3_ack_o(m3_ack),
// Master 4
.m4_dat_i(m4_dat_w),
.m4_dat_o(m4_dat_r),
.m4_adr_i(m4_adr),
.m4_cti_i(m4_cti),
.m4_we_i(m4_we),
.m4_sel_i(m4_sel),
.m4_cyc_i(m4_cyc),
.m4_stb_i(m4_stb),
.m4_ack_o(m4_ack),
// Slave 0
.s0_dat_i(s0_dat_r),
.s0_dat_o(s0_dat_w),
.s0_adr_o(s0_adr),
.s0_cti_o(s0_cti),
.s0_sel_o(s0_sel),
.s0_we_o(s0_we),
.s0_cyc_o(s0_cyc),
.s0_stb_o(s0_stb),
.s0_ack_i(s0_ack),
// Slave 1
.s1_dat_i(s1_dat_r),
.s1_dat_o(s1_dat_w),
.s1_adr_o(s1_adr),
.s1_cti_o(s1_cti),
.s1_sel_o(s1_sel),
.s1_we_o(s1_we),
.s1_cyc_o(s1_cyc),
.s1_stb_o(s1_stb),
.s1_ack_i(s1_ack),
// Slave 2
.s2_dat_i(s2_dat_r),
.s2_dat_o(s2_dat_w),
.s2_adr_o(s2_adr),
.s2_cti_o(s2_cti),
.s2_sel_o(s2_sel),
.s2_we_o(s2_we),
.s2_cyc_o(s2_cyc),
.s2_stb_o(s2_stb),
.s2_ack_i(s2_ack),
// Slave 3
.s3_dat_i(s3_dat_r),
.s3_dat_o(s3_dat_w),
.s3_adr_o(s3_adr),
.s3_cti_o(s3_cti),
.s3_sel_o(s3_sel),
.s3_we_o(s3_we),
.s3_cyc_o(s3_cyc),
.s3_stb_o(s3_stb),
.s3_ack_i(s3_ack),
// Slave 4
.s4_dat_i(s4_dat_r),
.s4_dat_o(s4_dat_w),
.s4_adr_o(s4_adr),
.s4_cti_o(s4_cti),
.s4_sel_o(s4_sel),
.s4_we_o(s4_we),
.s4_cyc_o(s4_cyc),
.s4_stb_o(s4_stb),
.s4_ack_i(s4_ack)
);
//---------------------------------------------------------------------------
// Masters
//---------------------------------------------------------------------------
wire m0_end;
master #(
.id(0)
) m0 (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.dat_w(m0_dat_w),
.dat_r(m0_dat_r),
.adr(m0_adr),
.cti(m0_cti),
.we(m0_we),
.sel(m0_sel),
.cyc(m0_cyc),
.stb(m0_stb),
.ack(m0_ack),
.tend(m0_end)
);
wire m1_end;
master #(
.id(1)
) m1 (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.dat_w(m1_dat_w),
.dat_r(m1_dat_r),
.adr(m1_adr),
.cti(m1_cti),
.we(m1_we),
.sel(m1_sel),
.cyc(m1_cyc),
.stb(m1_stb),
.ack(m1_ack),
.tend(m1_end)
);
wire m2_end;
master #(
.id(2)
) m2 (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.dat_w(m2_dat_w),
.dat_r(m2_dat_r),
.adr(m2_adr),
.cti(m2_cti),
.we(m2_we),
.sel(m2_sel),
.cyc(m2_cyc),
.stb(m2_stb),
.ack(m2_ack),
.tend(m2_end)
);
wire m3_end;
master #(
.id(3)
) m3 (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.dat_w(m3_dat_w),
.dat_r(m3_dat_r),
.adr(m3_adr),
.cti(m3_cti),
.we(m3_we),
.sel(m3_sel),
.cyc(m3_cyc),
.stb(m3_stb),
.ack(m3_ack),
.tend(m3_end)
);
wire m4_end;
master #(
.id(4)
) m4 (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.dat_w(m4_dat_w),
.dat_r(m4_dat_r),
.adr(m4_adr),
.cti(m4_cti),
.we(m4_we),
.sel(m4_sel),
.cyc(m4_cyc),
.stb(m4_stb),
.ack(m4_ack),
.tend(m4_end)
);
//---------------------------------------------------------------------------
// Slaves
//---------------------------------------------------------------------------
slave #(
.id(0)
) s0 (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.dat_w(s0_dat_w),
.dat_r(s0_dat_r),
.adr(s0_adr),
.cti(s0_cti),
.we(s0_we),
.sel(s0_sel),
.cyc(s0_cyc),
.stb(s0_stb),
.ack(s0_ack)
);
slave #(
.id(1)
) s1 (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.dat_w(s1_dat_w),
.dat_r(s1_dat_r),
.adr(s1_adr),
.cti(s1_cti),
.we(s1_we),
.sel(s1_sel),
.cyc(s1_cyc),
.stb(s1_stb),
.ack(s1_ack)
);
slave #(
.id(2)
) s2 (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.dat_w(s2_dat_w),
.dat_r(s2_dat_r),
.adr(s2_adr),
.cti(s2_cti),
.we(s2_we),
.sel(s2_sel),
.cyc(s2_cyc),
.stb(s2_stb),
.ack(s2_ack)
);
slave #(
.id(3)
) s3 (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.dat_w(s3_dat_w),
.dat_r(s3_dat_r),
.adr(s3_adr),
.cti(s3_cti),
.we(s3_we),
.sel(s3_sel),
.cyc(s3_cyc),
.stb(s3_stb),
.ack(s3_ack)
);
slave #(
.id(4)
) s4 (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.dat_w(s4_dat_w),
.dat_r(s4_dat_r),
.adr(s4_adr),
.cti(s4_cti),
.we(s4_we),
.sel(s4_sel),
.cyc(s4_cyc),
.stb(s4_stb),
.ack(s4_ack)
);
initial sys_clk = 1'b0;
always #5 sys_clk = ~sys_clk;
wire all_end = m0_end & m1_end & m2_end & m3_end & m4_end;
always begin
sys_rst = 1'b1;
@(posedge sys_clk);
#1 sys_rst = 1'b0;
@(posedge all_end);
$finish;
end
endmodule
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/csrbrg/ 0000775 0000000 0000000 00000000000 11632347016 0023755 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/csrbrg/rtl/ 0000775 0000000 0000000 00000000000 11632347016 0024556 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/csrbrg/rtl/csrbrg.v 0000664 0000000 0000000 00000003625 11632347016 0026235 0 ustar 00root root 0000000 0000000 /*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
module csrbrg(
input sys_clk,
input sys_rst,
/* WB */
input [31:0] wb_adr_i,
input [31:0] wb_dat_i,
output reg [31:0] wb_dat_o,
input wb_cyc_i,
input wb_stb_i,
input wb_we_i,
output reg wb_ack_o,
/* CSR */
output reg [13:0] csr_a,
output reg csr_we,
output reg [31:0] csr_do,
input [31:0] csr_di
);
/* Datapath: WB <- CSR */
always @(posedge sys_clk) begin
wb_dat_o <= csr_di;
end
/* Datapath: CSR -> WB */
reg next_csr_we;
always @(posedge sys_clk) begin
csr_a <= wb_adr_i[15:2];
csr_we <= next_csr_we;
csr_do <= wb_dat_i;
end
/* Controller */
reg [1:0] state;
reg [1:0] next_state;
parameter IDLE = 2'd0;
parameter DELAYACK1 = 2'd1;
parameter DELAYACK2 = 2'd2;
parameter ACK = 2'd3;
always @(posedge sys_clk) begin
if(sys_rst)
state <= IDLE;
else
state <= next_state;
end
always @(*) begin
next_state = state;
wb_ack_o = 1'b0;
next_csr_we = 1'b0;
case(state)
IDLE: begin
if(wb_cyc_i & wb_stb_i) begin
/* We have a request for us */
next_csr_we = wb_we_i;
if(wb_we_i)
next_state = ACK;
else
next_state = DELAYACK1;
end
end
DELAYACK1: next_state = DELAYACK2;
DELAYACK2: next_state = ACK;
ACK: begin
wb_ack_o = 1'b1;
next_state = IDLE;
end
endcase
end
endmodule
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/csrbrg/test/ 0000775 0000000 0000000 00000000000 11632347016 0024734 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/csrbrg/test/Makefile 0000664 0000000 0000000 00000000172 11632347016 0026374 0 ustar 00root root 0000000 0000000 SOURCES=tb_csrbrg.v $(wildcard ../rtl/*.v)
all: sim
sim:
cver $(SOURCES)
clean:
rm -f verilog.log
.PHONY: clean sim
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/csrbrg/test/tb_csrbrg.v 0000664 0000000 0000000 00000005673 11632347016 0027105 0 ustar 00root root 0000000 0000000 /*
* Milkymist SoC
* Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
module tb_csrbrg();
reg sys_clk;
reg sys_rst;
reg [31:0] wb_adr_i;
reg [31:0] wb_dat_i;
wire [31:0] wb_dat_o;
reg wb_cyc_i;
reg wb_stb_i;
reg wb_we_i;
wire wb_ack_o;
wire [13:0] csr_a;
wire csr_we;
wire [31:0] csr_do;
reg [31:0] csr_di;
/* 100MHz system clock */
initial sys_clk = 1'b0;
always #5 sys_clk = ~sys_clk;
csrbrg dut(
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.wb_adr_i(wb_adr_i),
.wb_dat_i(wb_dat_i),
.wb_dat_o(wb_dat_o),
.wb_cyc_i(wb_cyc_i),
.wb_stb_i(wb_stb_i),
.wb_we_i(wb_we_i),
.wb_ack_o(wb_ack_o),
/* CSR bus master */
.csr_a(csr_a),
.csr_we(csr_we),
.csr_do(csr_do),
.csr_di(csr_di)
);
task waitclock;
begin
@(posedge sys_clk);
#1;
end
endtask
task wbwrite;
input [31:0] address;
input [31:0] data;
integer i;
begin
wb_adr_i = address;
wb_dat_i = data;
wb_cyc_i = 1'b1;
wb_stb_i = 1'b1;
wb_we_i = 1'b1;
i = 0;
while(~wb_ack_o) begin
i = i+1;
waitclock;
end
waitclock;
$display("WB Write: %x=%x acked in %d clocks", address, data, i);
wb_cyc_i = 1'b0;
wb_stb_i = 1'b0;
wb_we_i = 1'b0;
end
endtask
task wbread;
input [31:0] address;
integer i;
begin
wb_adr_i = address;
wb_cyc_i = 1'b1;
wb_stb_i = 1'b1;
wb_we_i = 1'b0;
i = 0;
while(~wb_ack_o) begin
i = i+1;
waitclock;
end
$display("WB Read : %x=%x acked in %d clocks", address, wb_dat_o, i);
waitclock;
wb_cyc_i = 1'b0;
wb_stb_i = 1'b0;
wb_we_i = 1'b0;
end
endtask
/* Simulate CSR slave */
reg [31:0] csr1;
reg [31:0] csr2;
wire csr_selected = (csr_a[13:10] == 4'ha);
always @(posedge sys_clk) begin
if(csr_selected) begin
if(csr_we) begin
$display("Writing %x to CSR %x", csr_do, csr_a[0]);
case(csr_a[0])
1'b0: csr1 <= csr_do;
1'b1: csr2 <= csr_do;
endcase
end
case(csr_a[0])
1'b0: csr_di <= csr1;
1'b1: csr_di <= csr2;
endcase
end else
/* we must set data to 0 to be able to use a distributed OR topology
* in the slaves->master datapath.
*/
csr_di <= 32'd0;
end
always begin
/* Reset / Initialize our logic */
sys_rst = 1'b1;
wb_adr_i = 32'd0;
wb_dat_i = 32'd0;
wb_cyc_i = 1'b0;
wb_stb_i = 1'b0;
wb_we_i = 1'b0;
waitclock;
sys_rst = 1'b0;
waitclock;
/* Try some transfers */
wbwrite(32'h0000a000, 32'hcafebabe);
wbwrite(32'h0000a004, 32'habadface);
wbread(32'h0000a000);
wbread(32'h0000a004);
$finish;
end
endmodule
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/lm32/ 0000775 0000000 0000000 00000000000 11632347016 0023250 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/lm32/CHANGELOG 0000664 0000000 0000000 00000000264 11632347016 0024464 0 ustar 00root root 0000000 0000000 * 2009-12-21 Upgrade to LatticeMico32 3.5.
* 2009-11-12 Active-high interrupts (lekernel)
* 2009-07-01 Based on LatticeMico32 core from mico32_72_linux.tar.
(LatticeMico32 v3.3)
tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/lm32/doc/ 0000775 0000000 0000000 00000000000 11632347016 0024015 5 ustar 00root root 0000000 0000000 tdc-core-150af6c1d7afed4e2b9c413bc4f66eb3702c897b/demo/cores/lm32/doc/ds_icon.jpg 0000664 0000000 0000000 00000033620 11632347016 0026141 0 ustar 00root root 0000000 0000000 ÿØÿà JFIF H H ÿáÝExif MM * b j( 1 r2 ‡i ¤ Ð H H Adobe Photoshop CS Windows 2006:05:31 15:29:52 &( . § H H ÿØÿà JFIF H H ÿí Adobe_CM ÿî Adobe d€ ÿÛ „
ÿÀ " ÿÝ ÿÄ?
3 !1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷ 5 !1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ? êGÚºÎpÎϦ³Ñý"ìZ¬{v¸1ìÉ´?ü5þGèª>Þ„á^7Ds;\ìŠÚHüÒæŒGíÿ =ZÆ· t^U,¸~«C´¾–ŸæÃ}3ö£ÿ |MÖ3r˱½ë±¬»Ñy~÷\×þ—¯m_ÍWþÅhP» Ñaß̺?WëÇ«?$cWU5Y‹‹nÌxô‹žìÍÏÌmm³sZÏÒìý#êÁèVÙgVÏe h£«{lÍvfço`gï~uUÅåù_§ýÂÿ Ðúÿ Ý?ÿÐêpÛ‚:~9ØY‘Eu?~ÖAcC\ÆÙöwµÍßûŽØÍÄ®Ç?™xÆzv|ÚLÌwô_ÍrêÒSÜõôŸ·ÒÇQîòý*¼lÛ²-i¤dì§-cêôíµô^Ênk,¯¨>ûïþo'ôk¨XŸXþÁµ¾¿©¿Óèz{¾Í¬}£íß³þïø__ù•¯ú?å}å}üŸþ
•úî½Uòÿ o÷SÓ}/wÿÙÿí ˆPhotoshop 3.0 8BIM 8BIM% Fò‰&¸VÚ°œ¡°§w8BIMí H H 8BIM&