Skip to content
Snippets Groups Projects
Commit b0b19257 authored by Federico Vaga's avatar Federico Vaga
Browse files

Merge remote-tracking branch 'ohwr/proposed_master' into develop

parents 58695b59 6258b8df
Branches
Tags
No related merge requests found
Showing
with 1214 additions and 106 deletions
..
SPDX-License-Identifier: CC-BY-SA-4.0
SPDX-FileCopyrightText: 2019 CERN
SPDX-FileCopyrightText: 2019-2020 CERN
==========
Change Log
......@@ -9,19 +9,28 @@ Change Log
Format: `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_
Versioning: `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_
[1.0.3] - 2020-01-15
[Unreleased]
============
Added
-----
- [hdl] VHDL functions to convert characters and strings to upper/lower case.
Changed
-------
- [hdl] Rewritten the WB master interface used in simulations.
[1.0.3]_ - 2020-01-15
====================
Changed
-----
- [sw] add more file to .gitignore
[1.0.2] - 2019-10-24
[1.0.2]_ - 2019-10-24
====================
Fixed
-----
- [ci] forgot rule to publish RPMs
[1.0.1] - 2019-10-24
[1.0.1]_ - 2019-10-24
====================
Added
-----
......@@ -30,8 +39,15 @@ Changed
-------
- [sw] Makefiles have been changed to better support RPM generation
[1.0.0] - 2019-10-21
[1.0.0]_ - 2019-10-21
====================
Added
-----
- First release of general-cores.
.. _[Unreleased]: https://www.ohwr.org/project/general-cores/compare/v1.0.3...proposed_master
.. _[1.0.3]: https://www.ohwr.org/project/general-cores/tags/v1.0.3
.. _[1.0.2]: https://www.ohwr.org/project/general-cores/tags/v1.0.2
.. _[1.0.1]: https://www.ohwr.org/project/general-cores/tags/v1.0.1
.. _[1.0.0]: https://www.ohwr.org/project/general-cores/tags/v1.0.0
......@@ -13,13 +13,22 @@ In [modules/common](modules/common) there are general purpose cores:
* The package [matrix_pkg](modules/common/matrix_pkg.vhd) declares a 2d
array of std_logic, and some subprograms to handle it.
* Edge detectors are provided by [gc_posedge](modules/common/gc_posedge.vhd)
and [gc_negedge](modules/common/gc_negedge.vhd).
* For clock-domain crossing or asynchronous signal register, use
[gc_sync_ffs](modules/common/gc_sync_ffs.vhd). It also has an edge
detector.
[gc_sync](modules/common/gc_sync.vhd). This is the basic synchronizer.
If you also need an edge detector, use
[gc_sync_ffs](modules/common/gc_sync_ffs.vhd).
The other synchronizer [gc_sync_register](modules/common/gc_sync_register.vhd)
is deprecated. It can synchronize multiple signals at the same time but
doesn't ensure coherency between these signals.
The module [gc_sync_edge](modules/common/gc_sync_edge.vhd) provides a
synchronizer with an (positive or negative) edge detector. The signal
edge is always detected on the rising edge of the clock. This module is
simpler than the gc_sync_ffs module.
To pass words from one clock domain to another, you can use the module
[gc_sync_word_wr](modules/common/gc_sync_word_wr.vhd) for writing data,
and [gc_sync_word_rd](modules/common/gc_sync_word_rd.vhd) for reading
......@@ -197,6 +206,15 @@ Directory [modules/wishbone](modules/wishbone) contains modules for wishbone.
AT91SAM9x CPU external bus interface.
- [wb_axi4lite_bridge](modules/wishbone/wb_axi4lite_bridge) is an axi4lite
to wishbone bridge
- [wb16_to_wb32](modules/wishbone/wb16_to_wb32) is an adapter from a
16 data bit wishbone master to a 32 data bit wishbone slave. It uses
an intermediate register. Refer to the module for how to use it.
* There are modules for axi4 bus
- [axi4lite32_axi4full64_bridge](modules/axi/axi4lite32_axi4full64_bridge) is
a bridge from axi4full64 to axi4lite32. It was defined to interface with
the Vivado PCI-e bridge and doesn't support all the axi4full features
(in particular the burst accesses).
* There a modules to build a bus hierarchy:
- [wb_bus_fanout](modules/wishbone/wb_bus_fanout) is a simple master to
......
modules = { "local" : [
"z7_axi_gpio_expander",
"axi4lite_wb_bridge",
"axi4lite32_axi4full64_bridge",
]}
files = [
......
files = [
"axi4lite32_axi4full64_bridge.vhd",
];
-------------------------------------------------------------------------------
-- Title : AXI4Full64 to AXI4Lite32 bridge
-- Project : General Cores
-------------------------------------------------------------------------------
-- File : axi4lite32_axi4full64_bridge.vhd
-- Company : CERN
-- Platform : FPGA-generics
-- Standard : VHDL '93
-------------------------------------------------------------------------------
-- Copyright (c) 2019 CERN
--
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 0.51 (the "License") (which enables you, at your option,
-- to treat this file as licensed under the Apache License 2.0); you may not
-- use this file except in compliance with the License. You may obtain a copy
-- of the License at http://solderpad.org/licenses/SHL-0.51.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity axi4lite32_axi4full64_bridge is
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
-- AXI4-Full slave
s_awaddr : in STD_LOGIC_VECTOR (31 downto 0);
s_awlen : in STD_LOGIC_VECTOR (7 downto 0);
s_awsize : in STD_LOGIC_VECTOR (2 downto 0);
s_awburst : in STD_LOGIC_VECTOR (1 downto 0);
s_awvalid : in STD_LOGIC;
s_awready : out STD_LOGIC;
s_wdata : in STD_LOGIC_VECTOR (63 downto 0);
s_wstrb : in STD_LOGIC_VECTOR (7 downto 0);
s_wlast : in STD_LOGIC;
s_wvalid : in STD_LOGIC;
s_wready : out STD_LOGIC;
s_bresp : out STD_LOGIC_VECTOR (1 downto 0);
s_bvalid : out STD_LOGIC;
s_bready : in STD_LOGIC;
s_araddr : in STD_LOGIC_VECTOR (31 downto 0);
s_arlen : in STD_LOGIC_VECTOR (7 downto 0);
s_arsize : in STD_LOGIC_VECTOR (2 downto 0);
s_arburst : in STD_LOGIC_VECTOR (1 downto 0);
s_arvalid : in STD_LOGIC;
s_arready : out STD_LOGIC;
s_rdata : out STD_LOGIC_VECTOR (63 downto 0);
s_rresp : out STD_LOGIC_VECTOR (1 downto 0);
s_rlast : out STD_LOGIC;
s_rvalid : out STD_LOGIC;
s_rready : in STD_LOGIC;
-- AXI4-Lite master
m_awaddr : out STD_LOGIC_VECTOR (31 downto 0);
m_awvalid : out STD_LOGIC;
m_awready : in STD_LOGIC;
m_wdata : out STD_LOGIC_VECTOR (31 downto 0);
m_wstrb : out STD_LOGIC_VECTOR (3 downto 0);
m_wvalid : out STD_LOGIC;
m_wready : in STD_LOGIC;
m_bresp : in STD_LOGIC_VECTOR (1 downto 0);
m_bvalid : in STD_LOGIC;
m_bready : out STD_LOGIC;
m_araddr : out STD_LOGIC_VECTOR (31 downto 0);
m_arvalid : out STD_LOGIC;
m_arready : in STD_LOGIC;
m_rdata : in STD_LOGIC_VECTOR (31 downto 0);
m_rresp : in STD_LOGIC_VECTOR (1 downto 0);
m_rvalid : in STD_LOGIC;
m_rready : out STD_LOGIC
);
end axi4lite32_axi4full64_bridge;
architecture behav of axi4lite32_axi4full64_bridge is
constant RSP_OKAY : std_logic_vector(1 downto 0) := b"00";
constant RSP_EXOKAY : std_logic_vector(1 downto 0) := b"01";
constant RSP_SLVERR : std_logic_vector(1 downto 0) := b"10";
constant RSP_DECERR : std_logic_vector(1 downto 0) := b"11";
type t_wr_state is (WR_IDLE,
WR_MASTER, WR_SLAVE, WR_SLAVE2, WR_WAIT, WR_DONE);
type t_rd_state is (RD_IDLE, RD_READ, RD_SLAVE);
signal wstate : t_wr_state;
signal rstate : t_rd_state;
signal waddr : std_logic_vector(31 downto 0);
signal wlen : std_logic_vector(7 downto 0);
signal wsize : std_logic_vector(2 downto 0);
signal wdata : std_logic_vector(63 downto 0);
signal wstrb : std_logic_vector(7 downto 0);
signal raddr : std_logic_vector(31 downto 0);
signal rlen : std_logic_vector(7 downto 0);
signal rsize : std_logic_vector(2 downto 0);
signal rdata : std_logic_vector(63 downto 0);
begin
-- Write part.
m_awaddr <= waddr;
process (clk_i)
begin
if rising_edge (clk_i) then
if rst_n_i = '0' then
wstate <= WR_IDLE;
s_awready <= '1';
s_wready <= '0';
s_bvalid <= '0';
m_awvalid <= '0';
m_wvalid <= '0';
m_bready <= '0';
else
case wstate is
when WR_IDLE =>
-- Wait until awvalid is ready.
if s_awvalid = '1' then
-- Save transaction parameters
waddr <= s_awaddr;
wlen <= s_awlen;
wsize <= s_awsize;
-- Not anymore ready for addresses.
s_awready <= '0';
-- But ready for data.
s_wready <= '1';
wstate <= WR_MASTER;
end if;
when WR_MASTER =>
-- Clear wvalid when coming from WR_SLAVE.
m_wvalid <= '0';
if s_wvalid = '1' then
-- Got data from master.
wdata <= s_wdata;
wstrb <= s_wstrb;
s_wready <= '0';
-- Address cycle.
m_awvalid <= '1';
wstate <= WR_SLAVE;
end if;
when WR_SLAVE =>
if m_awready = '1' then
m_awvalid <= '0';
end if;
-- Prepare data write cycle.
if waddr (2) = '1' then
m_wdata <= wdata(63 downto 32);
m_wstrb <= wstrb(7 downto 4);
else
m_wdata <= wdata(31 downto 0);
m_wstrb <= wstrb(3 downto 0);
end if;
m_wvalid <= '1';
wstate <= WR_SLAVE2;
when WR_SLAVE2 =>
if m_awready = '1' then
m_awvalid <= '0';
end if;
if m_wready = '1' then
m_wvalid <= '0';
m_bready <= '1';
wstate <= WR_WAIT;
end if;
when WR_WAIT =>
-- End of transfer ?
if m_bvalid = '1' then
m_bready <= '0';
if waddr (2) = '1'
or (wsize (1 downto 0) = "10" and waddr (1) /= '1') -- 4 bytes
or (wsize (1 downto 0) = "01" and waddr (1 downto 0) /= "11")
or wsize (1 downto 0) = "00" -- 1 byte
then
if wlen = x"00" then
-- End of the burst.
s_bresp <= RSP_OKAY;
s_bvalid <= '1';
wstate <= WR_DONE;
else
wlen <= std_logic_vector(unsigned(wlen) - 1);
-- TODO: adjust address.
s_wready <= '1';
wstate <= WR_MASTER;
end if;
else
-- Next part of the data.
waddr (2) <= '1';
m_awvalid <= '1';
wstate <= WR_SLAVE;
end if;
end if;
when WR_DONE =>
if s_bready = '1' then
s_bvalid <= '0';
s_awready <= '1';
wstate <= WR_IDLE;
end if;
end case;
end if;
end if;
end process;
-- Read part.
m_araddr <= raddr;
s_rdata <= rdata;
process (clk_i)
begin
if rising_edge (clk_i) then
if rst_n_i = '0' then
rstate <= RD_IDLE;
s_arready <= '1';
s_rvalid <= '0';
s_rlast <= '0';
m_arvalid <= '0';
m_rready <= '0';
raddr <= (others => 'X');
rdata <= (others => '0');
else
case rstate is
when RD_IDLE =>
-- Wait until awvalid is ready.
if s_arvalid = '1' then
-- Save transaction parameters
raddr <= s_araddr;
rlen <= s_arlen;
rsize <= s_arsize;
-- Provide a clean result.
rdata <= (others => '0');
-- Not anymore ready for addresses.
s_arready <= '0';
-- Start transfer on the slave part.
m_arvalid <= '1';
m_rready <= '1';
rstate <= RD_READ;
end if;
when RD_READ =>
if m_arready = '1' then
m_arvalid <= '0';
end if;
if m_rvalid = '1' then
-- Read data. Address must have been acked.
-- According to A3.4.3 of AXI4 spec, the AXI4 bus is little
-- endian.
if raddr (2) = '1' then
rdata (63 downto 32) <= m_rdata;
else
rdata (31 downto 0) <= m_rdata;
end if;
-- End of transfer on the master ?
if raddr (2) = '1'
or (rsize (1 downto 0) = "10" and raddr (1) /= '1') -- 4 bytes
or (rsize (1 downto 0) = "01" and raddr (1 downto 0) /= "11")
or rsize (1 downto 0) = "00" -- 1 byte
then
-- To master.
rstate <= RD_SLAVE;
s_rresp <= RSP_OKAY;
if rlen = x"00" then
s_rlast <= '1';
else
s_rlast <= '0';
end if;
s_rvalid <= '1';
else
-- Next transfer.
raddr (2) <= '1';
m_arvalid <= '1';
m_rready <= '1';
end if;
end if;
when RD_SLAVE =>
if s_rready = '1' then
s_rvalid <= '0';
if rlen = x"00" then
-- End of the burst.
s_arready <= '1';
rstate <= RD_IDLE;
else
rlen <= std_logic_vector(unsigned(rlen) - 1);
-- TODO: adjust address.
-- New beat.
m_arvalid <= '1';
m_rready <= '1';
rstate <= RD_READ;
end if;
end if;
end case;
end if;
end if;
end process;
end behav;
......@@ -11,6 +11,11 @@ files = [
"gc_serial_dac.vhd",
"gc_sync_ffs.vhd",
"gc_arbitrated_mux.vhd",
"gc_sync_register.vhd",
"gc_sync.vhd",
"gc_posedge.vhd",
"gc_negedge.vhd",
"gc_sync_edge.vhd",
"gc_pulse_synchronizer.vhd",
"gc_pulse_synchronizer2.vhd",
"gc_frequency_meter.vhd",
......@@ -25,10 +30,10 @@ files = [
"gc_big_adder.vhd",
"gc_fsm_watchdog.vhd",
"gc_bicolor_led_ctrl.vhd",
"gc_sync_register.vhd",
"gc_single_reset_gen.vhd",
"gc_async_signals_input_stage.vhd",
"gc_dec_8b10b.vhd",
"gc_enc_8b10b.vhd",
"gc_dyn_extend_pulse.vhd",
"gc_ds182x_interface.vhd",
"gc_ds182x_readout/gc_ds182x_readout.vhd",
......
--------------------------------------------------------------------------------
-- GSI
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- unit name: enc_8b10b
--
-- author(s): Mathias Kreider, Vladimir Cherkashyn
--
-- description: 8b/10b Encoder
-- This module provides 8bit-to-10bit encoding. It accepts 8-bit parallel
-- data input and generates 10-bit encoded data output in accordance with
-- the 8b/10b standard. IO latency is one clock cycle.
--
-- This approach uses a mix of LUTs and stacked ifs, unlike the suggested
-- approach that only used gates. This uses more logic cells, but also runs
-- about twice as fast. The reverse vector function is used because all code
-- tables are provided in literature as LSB first. This way, the sourcecode
-- is easier to compare.
--
--------------------------------------------------------------------------------
-- Copyright GSI 2009-2020
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.gencores_pkg.all;
entity gc_enc_8b10b is
generic
(
g_USE_INTERNAL_RUNNING_DISPARITY : boolean := TRUE);
port
(
clk_i : in std_logic; -- byte clock, trigger on rising edge
rst_n_i : in std_logic; -- reset, assert HI
ctrl_i : in std_logic; -- control char, assert HI
in_8b_i : in std_logic_vector(7 downto 0); -- 8bit input
err_o : out std_logic; -- HI if ctrl_i is HI and input is not a valid control byte
dispar_i : in std_logic := '0';
dispar_o : out std_logic; -- running disparity: HI = +1, LO = 0
out_10b_o : out std_logic_vector(9 downto 0) -- 10bit codeword output
);
end gc_enc_8b10b;
architecture rtl of gc_enc_8b10b is
--=============================================================================
-- LOOKUP TABLES
--=============================================================================
constant c_RD_MINUS : std_logic := '0';
constant c_RD_PLUS : std_logic := '1';
-- type for 5b/6b Code Table
type t_enc_5b_6b is array(integer range <>) of std_logic_vector(5 downto 0);
-- type for 5b/6b Code Table
type t_enc_3b_4b is array(integer range <>) of std_logic_vector(3 downto 0);
-- 5b/6b Code Table
constant c_ENC_5B_6B_TABLE : t_enc_5b_6b (0 to 31) :=
("100111", -- D00
"011101", -- D01
"101101", -- D02
"110001", -- D03
"110101", -- D04
"101001", -- D05
"011001", -- D06
"111000", -- D07
"111001", -- D08
"100101", -- D09
"010101", -- D10
"110100", -- D11
"001101", -- D12
"101100", -- D13
"011100", -- D14
"010111", -- D15
"011011", -- D16
"100011", -- D17
"010011", -- D18
"110010", -- D19
"001011", -- D20
"101010", -- D21
"011010", -- D22
"111010", -- D23
"110011", -- D24
"100110", -- D25
"010110", -- D26
"110110", -- D27
"001110", -- D28
"101110", -- D29
"011110", -- D30
"101011"); -- D31
-- 5b/6b Disparity Table
constant c_DISPAR_6B : std_logic_vector(0 to 31) :=
(
"11101000100000011000000110010111");
-- 3b/4b Code Table
constant c_ENC_3B_4B_TABLE : t_enc_3b_4b (0 to 7) :=
("1011", -- Dx0
"1001", -- Dx1
"0101", -- Dx2
"1100", -- Dx3
"1101", -- Dx4
"1010", -- Dx5
"0110", -- Dx6
"1110"); -- DxP7
-- 3b/4b Disparity Table
constant c_DISPAR_4B : std_logic_vector(0 to 7) :=
(
"10001001");
--=============================================================================
-- INTERNAL SIGNALS
--=============================================================================
signal s_ind5b : integer := 0; -- LUT 5b index
signal s_ind3b : integer := 0; -- LUT 3b index
signal s_val6bit : std_logic_vector(5 downto 0); -- 6bit code
signal s_val6bit_n : std_logic_vector(5 downto 0); -- 6bit code inverted
signal s_val4bit : std_logic_vector(3 downto 0); -- 4bit code
signal s_val4bit_n : std_logic_vector(3 downto 0); -- 4bit code inverted
-- code disparity 6b code: HI = uneven number of bits, LO = even, neutral disp
signal s_dP6bit : std_logic := '0';
-- code disparity 4b code: HI = uneven number of bits, LO = even, neutral disp
signal s_dP4bit : std_logic := '0';
-- output 10b signal buffer
signal s_out_10b, s_out_10b_reg : std_logic_vector(9 downto 0) := (others => '0');
signal s_in_8b_reg : std_logic_vector(7 downto 0); -- input 8b signal buffer
signal s_err, s_err_reg : std_logic; -- output err signal buffer
signal s_ctrl_reg : std_logic; -- output dispar, ctrl signal buffers
signal s_dpTrack : std_logic := c_RD_MINUS; -- current disparity: Hi = +1, LO = 0
signal s_RunDisp : std_logic; -- running disparity register
signal s_RunDisp_reg : std_logic; -- running disparity register
signal s_RunDisp_comb : std_logic; -- running disparity register
begin
s_RunDisp <= s_RunDisp_reg when g_USE_INTERNAL_RUNNING_DISPARITY else dispar_i;
dispar_o <= s_RunDisp_comb;
--=============================================================================
-- CONCURRENT COMMANDS
--=============================================================================
-- use 3bit at 7-5 as index for 4bit code and disparity table \n
s_ind3b <= to_integer(unsigned(s_in_8b_reg(7 downto 5)));
s_val4bit <= c_ENC_3B_4B_TABLE(s_ind3b);
s_dP4bit <= c_DISPAR_4B(s_ind3b);
s_val4bit_n <= not (s_val4bit);
-- use 5bit at 4-0 as index for 6bit code and disparity table
s_ind5b <= to_integer(unsigned(s_in_8b_reg(4 downto 0)));
s_val6bit <= c_ENC_5B_6B_TABLE(s_ind5b);
s_dP6bit <= c_DISPAR_6B(s_ind5b);
s_val6bit_n <= not (s_val6bit);
-- output wires
err_o <= s_err_reg;
out_10b_o <= s_out_10b_reg;
--=============================================================================
-- ENCODING
--=============================================================================
-- Process encodes 8bit value to 10bit codeword depending on current disparity
p_encoding : process (s_RunDisp, s_ctrl_reg, s_dP4bit, s_dP6bit, s_in_8b_reg,
s_val4bit, s_val4bit_n, s_val6bit, s_val6bit_n)
-- buffers ctrl code during selection
variable v_ctrl_code : std_logic_vector(9 downto 0) := (others => '0');
begin
v_ctrl_code := (others => '0');
s_err <= '0';
--========================================================================
-- TRANSMISSION CONTROL CODES
--========================================================================
if s_ctrl_reg = '1' then -- Control Char selected
-- control byte directly selects control code
case s_in_8b_reg is
when "00011100" => v_ctrl_code := f_reverse_vector("0011110100");
when "00111100" => v_ctrl_code := f_reverse_vector("0011111001");
when "01011100" => v_ctrl_code := f_reverse_vector("0011110101");
when "01111100" => v_ctrl_code := f_reverse_vector("0011110011");
when "10011100" => v_ctrl_code := f_reverse_vector("0011110010");
when "10111100" => v_ctrl_code := f_reverse_vector("0011111010");
when "11011100" => v_ctrl_code := f_reverse_vector("0011110110");
when "11111100" => v_ctrl_code := f_reverse_vector("0011111000");
when "11110111" => v_ctrl_code := f_reverse_vector("1110101000");
when "11111011" => v_ctrl_code := f_reverse_vector("1101101000");
when "11111101" => v_ctrl_code := f_reverse_vector("1011101000");
when "11111110" => v_ctrl_code := f_reverse_vector("0111101000");
when others => s_err <= '1';
end case;
-- select the right disparity and assign to output
if (s_RunDisp = c_RD_MINUS) then
s_out_10b <= v_ctrl_code;
else
s_out_10b <= not(v_ctrl_code);
end if;
else
--====================================================================
-- DATA CODES
--====================================================================
s_out_10b <= f_reverse_vector(s_val6bit & s_val4bit);
if s_RunDisp = c_RD_MINUS then
if s_dP4bit = s_dP6bit then
if s_dP6bit = '1' then
s_out_10b(9 downto 6) <= f_reverse_vector(s_val4bit_n);
end if;
else
if s_dP4bit = '1' then
if ((s_val6bit(2 downto 0) = "011") and
(s_val4bit(3 downto 1) = "111")) then
s_out_10b(9 downto 6) <= "1110";
end if;
else
if (s_val4bit = "1100") then
s_out_10b(9 downto 6) <= f_reverse_vector(s_val4bit_n);
end if;
end if;
end if;
else
if s_dP6bit = '1' then
s_out_10b(5 downto 0) <= f_reverse_vector(s_val6bit_n);
else
if (s_val6bit = "111000") then
s_out_10b(5 downto 0) <= f_reverse_vector(s_val6bit_n);
end if;
if s_dP4bit = '1' then
if ((s_val6bit(2 downto 0) = "100") and
(s_val4bit(3 downto 1) = "111")) then
s_out_10b(9 downto 6) <= "0001";
else
s_out_10b(9 downto 6) <= f_reverse_vector(s_val4bit_n);
end if;
else
if (s_val4bit = "1100") then
s_out_10b(9 downto 6) <= f_reverse_vector(s_val4bit_n);
end if;
end if;
end if;
end if;
end if;
end process p_encoding;
p_disp_fsm_next : process(s_RunDisp, s_ctrl_reg, s_dP4bit, s_dP6bit,
s_in_8b_reg)
begin
s_RunDisp_comb <= s_RunDisp;
if s_RunDisp = c_RD_MINUS then
if (s_ctrl_reg xor s_dP6bit xor s_dP4bit) /= '0' then
s_RunDisp_comb <= c_RD_PLUS;
end if;
else -- RD_PLUS
if (s_ctrl_reg xor s_dP6bit xor s_dP4bit) /= '0' then
s_RunDisp_comb <= c_RD_MINUS;
end if;
end if;
if (s_in_8b_reg(1 downto 0) /= "00" and s_ctrl_reg = '1') then
s_RunDisp_comb <= s_RunDisp;
end if;
end process p_disp_fsm_next;
p_disp_fsm_seq : process(clk_i)
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
s_RunDisp_reg <= c_RD_MINUS;
else
s_RunDisp_reg <= s_RunDisp_comb;
end if;
end if;
end process p_disp_fsm_seq;
s_ctrl_reg <= ctrl_i;
s_in_8b_reg <= in_8b_i;
p_inout_buffers : process(clk_i)
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
s_err_reg <= '0';
s_out_10b_reg <= B"0000_000000";
else
s_err_reg <= s_err;
s_out_10b_reg <= s_out_10b;
end if;
end if;
end process p_inout_buffers;
end architecture rtl;
......@@ -22,6 +22,21 @@
-- and limitations under the License.
--------------------------------------------------------------------------------
-- Principle of operation:
--
-- This block counts the number of pulses on CLK_IN_I during a period.
-- At the end of the period, the value is saved and the counter reset.
-- The saved value is available on FREQ_O, which is synchronized with
-- CLK_SYS_I if G_SYNC_OUT is True.
-- The width of the counter is defined by G_COUNTER_BITS.
--
-- - If g_WITH_INTERNAL_TIMEBASE is True:
-- The period is defined by an internal counter that generates a pulse
-- every G_CLK_SYS_FREQ CLK_SYS_I ticks.
--
-- - If g_WITH_INTERNAL_TIMEBASE is False:
-- The period is defined by PPS_P1_I
library ieee;
use ieee.std_logic_1164.all;
......
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- unit name: gc_negedge
--
-- description: Simple falling edge detector. Combinatorial.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2020
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity gc_negedge is
port(
clk_i : in std_logic; -- clock
rst_n_i : in std_logic; -- reset
data_i : in std_logic; -- input
pulse_o : out std_logic); -- falling edge detect output
end entity gc_negedge;
architecture arch of gc_negedge is
signal dff : std_logic;
begin
pulse_o <= not data_i and dff;
process (clk_i)
begin
if rising_edge (clk_i) then
if rst_n_i = '0' then
dff <= '0';
else
dff <= data_i;
end if;
end if;
end process;
end arch;
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- unit name: gc_posedge
--
-- description: Simple rising edge detector. Combinatorial.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2020
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity gc_posedge is
port(
clk_i : in std_logic; -- clock
rst_n_i : in std_logic; -- reset
data_i : in std_logic; -- input
pulse_o : out std_logic); -- positive edge detect output
end entity gc_posedge;
architecture arch of gc_posedge is
signal dff : std_logic;
begin
pulse_o <= data_i and not dff;
process (clk_i)
begin
if rising_edge (clk_i) then
if rst_n_i = '0' then
dff <= '0';
else
dff <= data_i;
end if;
end if;
end process;
end arch;
......@@ -89,12 +89,18 @@ begin -- rtl
d_ack_d0 <= d_ack;
if ready = '1' and d_p_i = '1' and d_p_d0 = '0'then
-- Incoming pulse detected and the system is ready.
-- Transfer it.
in_ext <= '1';
-- Clear ack and ready!
d_ack <= '0';
ready <= '0';
elsif in_ext = '1' and out_feedback = '1' then
-- Pulse has been transfered, clear the input.
in_ext <= '0';
elsif in_ext = '0' and out_feedback = '0' then
-- Clear transfered. Done.
-- This is also the steady state.
d_ack <= '1';
ready <= '1';
end if;
......
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- unit name: gc_sync
--
-- description: Elementary synchronizer chain using two flip-flops.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2014-2018
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity gc_sync is
generic(
g_sync_edge : string := "positive");
port (
clk_i : in std_logic;
rst_n_a_i : in std_logic;
d_i : in std_logic;
q_o : out std_logic);
end gc_sync;
-- make Altera Quartus quiet regarding unknown attributes:
-- altera message_off 10335
architecture arch of gc_sync is
-- Use an intermediate signal with a particular name and a keep attribute
-- so that it can be referenced in the constraints in order to ignore
-- timing (TIG) on that signal.
signal gc_sync_ffs_in : std_logic;
signal sync0, sync1 : std_logic;
attribute rloc : string;
attribute rloc of sync0 : signal is "X0Y0";
attribute rloc of sync1 : signal is "X0Y0";
attribute shreg_extract : string;
attribute shreg_extract of sync0 : signal is "no";
attribute shreg_extract of sync1 : signal is "no";
attribute keep : string;
attribute keep of gc_sync_ffs_in : signal is "true";
attribute keep of sync0 : signal is "true";
attribute keep of sync1 : signal is "true";
attribute keep_hierarchy : string;
attribute keep_hierarchy of arch : architecture is "true";
attribute async_reg : string;
attribute async_reg of sync0 : signal is "true";
attribute async_reg of sync1 : signal is "true";
begin
assert g_sync_edge = "positive" or g_sync_edge = "negative" severity failure;
gc_sync_ffs_in <= d_i;
sync_posedge : if (g_sync_edge = "positive") generate
process(clk_i, rst_n_a_i)
begin
if rst_n_a_i = '0' then
sync1 <= '0';
sync0 <= '0';
elsif rising_edge(clk_i) then
sync0 <= gc_sync_ffs_in;
sync1 <= sync0;
end if;
end process;
end generate sync_posedge;
sync_negedge : if(g_sync_edge = "negative") generate
process(clk_i, rst_n_a_i)
begin
if rst_n_a_i = '0' then
sync1 <= '0';
sync0 <= '0';
elsif falling_edge(clk_i) then
sync0 <= gc_sync_ffs_in;
sync1 <= sync0;
end if;
end process;
end generate sync_negedge;
q_o <= sync1;
end arch;
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- unit name: gc_sync_edge
--
-- description: Synchronizer chain and edge detector.
-- All the registers in the chain are cleared at reset.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2010-2018
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity gc_sync_edge is
generic(
g_edge : string := "positive");
port(
clk_i : in std_logic; -- clock from the destination clock domain
rst_n_a_i : in std_logic; -- async reset
data_i : in std_logic; -- async input
synced_o : out std_logic; -- synchronized output
pulse_o : out std_logic); -- edge detect output
end entity gc_sync_edge;
architecture arch of gc_sync_edge is
signal sync : std_logic;
begin
inst_sync : entity work.gc_sync
port map (
clk_i => clk_i,
rst_n_a_i => rst_n_a_i,
d_i => data_i,
q_o => sync);
assert g_edge = "positive" or g_edge = "negative" severity FAILURE;
sync_posedge : if g_edge = "positive" generate
inst_pedge : entity work.gc_posedge
port map (
clk_i => clk_i,
rst_n_i => rst_n_a_i,
data_i => sync,
pulse_o => pulse_o);
end generate;
sync_negedge : if g_edge = "negative" generate
inst_pedge : entity work.gc_negedge
port map (
clk_i => clk_i,
rst_n_i => rst_n_a_i,
data_i => sync,
pulse_o => pulse_o);
end generate;
end architecture arch;
......@@ -31,66 +31,53 @@ entity gc_sync_ffs is
g_sync_edge : string := "positive");
port(
clk_i : in std_logic; -- clock from the destination clock domain
rst_n_i : in std_logic; -- reset
rst_n_i : in std_logic; -- async reset
data_i : in std_logic; -- async input
synced_o : out std_logic; -- synchronized output
npulse_o : out std_logic; -- negative edge detect output
ppulse_o : out std_logic); -- positive edge detect output
end entity gc_sync_ffs;
-- make Altera Quartus quiet regarding unknown attributes:
-- altera message_off 10335
architecture arch of gc_sync_ffs is
signal sync0, sync1, sync2 : std_logic;
signal gc_sync_ffs_in : std_logic;
attribute shreg_extract : string;
attribute shreg_extract of sync0 : signal is "no";
attribute shreg_extract of sync1 : signal is "no";
attribute shreg_extract of sync2 : signal is "no";
attribute keep : string;
attribute keep of sync0 : signal is "true";
attribute keep of sync1 : signal is "true";
attribute rloc : string;
attribute rloc of sync0 : signal is "X0Y0";
attribute rloc of sync1 : signal is "X0Y0";
attribute keep of gc_sync_ffs_in : signal is "true";
-- synchronizer attribute for Vivado
attribute ASYNC_REG : string;
attribute ASYNC_REG of sync0 : signal is "true";
attribute ASYNC_REG of sync1 : signal is "true";
attribute ASYNC_REG of sync2 : signal is "true";
signal sync, npulse, ppulse : std_logic;
begin
-- rename data_i to something we can use as wildcard
-- in timing constraints
gc_sync_ffs_in <= data_i;
cmp_gc_sync : entity work.gc_sync
generic map (
g_sync_edge => g_sync_edge)
port map (
clk_i => clk_i,
rst_n_a_i => rst_n_i,
d_i => data_i,
q_o => sync);
cmp_gc_posedge : entity work.gc_posedge
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
data_i => sync,
pulse_o => ppulse);
cmp_gc_negedge : entity work.gc_negedge
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
data_i => sync,
pulse_o => npulse);
sync_posedge : if (g_sync_edge = "positive") generate
process(clk_i, rst_n_i)
begin
if(rst_n_i = '0') then
sync0 <= '0';
sync1 <= '0';
sync2 <= '0';
synced_o <= '0';
npulse_o <= '0';
ppulse_o <= '0';
elsif rising_edge(clk_i) then
sync0 <= gc_sync_ffs_in;
sync1 <= sync0;
sync2 <= sync1;
synced_o <= sync1;
npulse_o <= sync2 and not sync1;
ppulse_o <= not sync2 and sync1;
synced_o <= sync;
npulse_o <= npulse;
ppulse_o <= ppulse;
end if;
end process;
end generate sync_posedge;
......@@ -99,19 +86,13 @@ begin
process(clk_i, rst_n_i)
begin
if(rst_n_i = '0') then
sync0 <= '0';
sync1 <= '0';
sync2 <= '0';
synced_o <= '0';
npulse_o <= '0';
ppulse_o <= '0';
elsif falling_edge(clk_i) then
sync0 <= gc_sync_ffs_in;
sync1 <= sync0;
sync2 <= sync1;
synced_o <= sync1;
npulse_o <= sync2 and not sync1;
ppulse_o <= not sync2 and sync1;
synced_o <= sync;
npulse_o <= npulse;
ppulse_o <= ppulse;
end if;
end process;
end generate sync_negedge;
......
......@@ -53,7 +53,10 @@ architecture rtl of gc_sync_register is
attribute keep of gc_sync_register_in : signal is "true";
attribute keep of sync0 : signal is "true";
attribute keep of sync1 : signal is "true";
attribute keep_hierarchy : string;
attribute keep_hierarchy of rtl : architecture is "true";
attribute async_reg : string;
attribute async_reg of gc_sync_register_in : signal is "true";
attribute async_reg of sync0 : signal is "true";
......
......@@ -27,10 +27,60 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
package gencores_pkg is
--============================================================================
-- Procedures and functions
--============================================================================
procedure f_rr_arbitrate (
signal req : in std_logic_vector;
signal pre_grant : in std_logic_vector;
signal grant : out std_logic_vector);
function f_onehot_decode(x : std_logic_vector; size : integer) return std_logic_vector;
function f_big_ripple(a, b : std_logic_vector; c : std_logic) return std_logic_vector;
function f_gray_encode(x : std_logic_vector) return std_logic_vector;
function f_gray_decode(x : std_logic_vector; step : natural) return std_logic_vector;
function f_log2_ceil(N : natural) return positive;
-- kept for backwards compatibility, same as f_log2_ceil()
function log2_ceil(N : natural) return positive;
function f_bool2int (b : boolean) return natural;
function f_int2bool (n : natural) return boolean;
-- Convert a boolean to std_logic ('1' for True, '0' for False).
function f_to_std_logic(b : boolean) return std_logic;
-- Reduce-OR an std_logic_vector to std_logic
function f_reduce_or (x : std_logic_vector) return std_logic;
-- Character/String to std_logic_vector
function f_to_std_logic_vector (c : character) return std_logic_vector;
function f_to_std_logic_vector (s : string) return std_logic_vector;
-- Functions for short-hand if assignments
function f_pick (cond : boolean; if_1 : std_logic; if_0 : std_logic)
return std_logic;
function f_pick (cond : boolean; if_1 : std_logic_vector; if_0 : std_logic_vector)
return std_logic_vector;
function f_pick (cond : std_logic; if_1 : std_logic; if_0 : std_logic)
return std_logic;
function f_pick (cond : std_logic; if_1 : std_logic_vector; if_0 : std_logic_vector)
return std_logic_vector;
-- Functions to convert characters and strings to upper/lower case
function to_upper(c : character) return character;
function to_lower(c : character) return character;
function to_upper(s : string) return string;
function to_lower(s : string) return string;
-- Bit reversal function
function f_reverse_vector (a : in std_logic_vector) return std_logic_vector;
--============================================================================
-- Component instantiations
--============================================================================
......@@ -198,6 +248,46 @@ package gencores_pkg is
ppulse_o : out std_logic);
end component;
component gc_sync is
generic (
g_sync_edge : string := "positive");
port (
clk_i : in std_logic;
rst_n_a_i : in std_logic;
d_i : in std_logic;
q_o : out std_logic);
end component gc_sync;
component gc_sync_edge is
generic (
g_edge : string := "positive");
port (
clk_i : in std_logic;
rst_n_a_i : in std_logic;
data_i : in std_logic;
synced_o : out std_logic;
pulse_o : out std_logic);
end component gc_sync_edge;
------------------------------------------------------------------------------
-- Edge detectors
------------------------------------------------------------------------------
component gc_negedge is
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
data_i : in std_logic;
pulse_o : out std_logic);
end component gc_negedge;
component gc_posedge is
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
data_i : in std_logic;
pulse_o : out std_logic);
end component gc_posedge;
------------------------------------------------------------------------------
-- Pulse synchroniser
------------------------------------------------------------------------------
......@@ -295,7 +385,7 @@ package gencores_pkg is
d_req_o : out std_logic_vector(g_num_inputs-1 downto 0);
q_o : out std_logic_vector(g_width-1 downto 0);
q_valid_o : out std_logic;
q_input_id_o : out std_logic_vector(f_log2_size(g_num_inputs)-1 downto 0));
q_input_id_o : out std_logic_vector(f_log2_ceil(g_num_inputs)-1 downto 0));
end component;
------------------------------------------------------------------------------
......@@ -690,42 +780,6 @@ package gencores_pkg is
counter_o : out std_logic_vector(g_bits downto 0));
end component gc_async_counter_diff;
--============================================================================
-- Procedures and functions
--============================================================================
procedure f_rr_arbitrate (
signal req : in std_logic_vector;
signal pre_grant : in std_logic_vector;
signal grant : out std_logic_vector);
function f_onehot_decode(x : std_logic_vector; size : integer) return std_logic_vector;
function f_big_ripple(a, b : std_logic_vector; c : std_logic) return std_logic_vector;
function f_gray_encode(x : std_logic_vector) return std_logic_vector;
function f_gray_decode(x : std_logic_vector; step : natural) return std_logic_vector;
function log2_ceil(N : natural) return positive;
function f_bool2int (b : boolean) return natural;
function f_int2bool (n : natural) return boolean;
-- Convert a boolean to std_logic ('1' for True, '0' for False).
function f_to_std_logic(b : boolean) return std_logic;
-- Reduce-OR an std_logic_vector to std_logic
function f_reduce_or (x : std_logic_vector) return std_logic;
-- Character/String to std_logic_vector
function f_to_std_logic_vector (c : character) return std_logic_vector;
function f_to_std_logic_vector (s : string) return std_logic_vector;
-- Functions for short-hand if assignments
function f_pick (cond : boolean; if_1 : std_logic; if_0 : std_logic)
return std_logic;
function f_pick (cond : boolean; if_1 : std_logic_vector; if_0 : std_logic_vector)
return std_logic_vector;
function f_pick (cond : std_logic; if_1 : std_logic; if_0 : std_logic)
return std_logic;
function f_pick (cond : std_logic; if_1 : std_logic_vector; if_0 : std_logic_vector)
return std_logic_vector;
end package;
package body gencores_pkg is
......@@ -827,17 +881,22 @@ package body gencores_pkg is
------------------------------------------------------------------------------
-- Returns log of 2 of a natural number
------------------------------------------------------------------------------
function log2_ceil(N : natural) return positive is
function f_log2_ceil(N : natural) return positive is
begin
if N <= 2 then
return 1;
elsif N mod 2 = 0 then
return 1 + log2_ceil(N/2);
return 1 + f_log2_ceil(N/2);
else
return 1 + log2_ceil((N+1)/2);
return 1 + f_log2_ceil((N+1)/2);
end if;
end;
-- kept for backwards compatibility
function log2_ceil(N : natural) return positive is
begin
return f_log2_ceil(N);
end;
------------------------------------------------------------------------------
-- Converts a boolean to natural integer (false -> 0, true -> 1)
......@@ -954,4 +1013,59 @@ package body gencores_pkg is
return f_pick (f_to_std_logic(cond), if_1, if_0);
end function f_pick;
------------------------------------------------------------------------------
-- Functions to convert characters and strings to upper/lower case
------------------------------------------------------------------------------
function to_upper(c : character) return character is
variable i : integer;
begin
i := character'pos(c);
if (i > 96 and i < 123) then
i := i - 32;
end if;
return character'val(i);
end function to_upper;
function to_lower(c : character) return character is
variable i : integer;
begin
i := character'pos(c);
if (i > 64 and i < 91) then
i := i + 32;
end if;
return character'val(i);
end function to_lower;
function to_upper(s : string) return string is
variable uppercase : string (s'range);
begin
for i in s'range loop
uppercase(i) := to_upper(s(i));
end loop;
return uppercase;
end to_upper;
function to_lower(s : string) return string is
variable lowercase : string (s'range);
begin
for i in s'range loop
lowercase(i) := to_lower(s(i));
end loop;
return lowercase;
end to_lower;
------------------------------------------------------------------------------
-- Vector bit reversal
------------------------------------------------------------------------------
function f_reverse_vector (a : in std_logic_vector) return std_logic_vector is
variable v_result : std_logic_vector(a'reverse_range);
begin
for i in a'range loop
v_result(i) := a(i);
end loop;
return v_result;
end function f_reverse_vector;
end gencores_pkg;
......@@ -83,6 +83,10 @@ entity inferred_async_fifo is
rd_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0)
);
attribute keep_hierarchy : string;
attribute keep_hierarchy of
inferred_async_fifo : entity is "true";
end inferred_async_fifo;
......
......@@ -74,6 +74,10 @@ entity inferred_async_fifo_dual_rst is
rd_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0)
);
attribute keep_hierarchy : string;
attribute keep_hierarchy of
inferred_async_fifo_dual_rst : entity is "true";
end inferred_async_fifo_dual_rst;
......
......@@ -26,6 +26,9 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.gencores_pkg.all;
package genram_pkg is
function f_log2_size (A : natural) return natural;
......@@ -248,14 +251,10 @@ end genram_pkg;
package body genram_pkg is
-- kept for backwards compatibility
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);
return f_log2_ceil(A);
end function f_log2_size;
function f_gen_dummy_vec (val : std_logic; size : natural) return std_logic_vector is
......
......@@ -26,6 +26,7 @@ modules = { "local" : [
"wb_ds182x_readout",
"wb_metadata",
"wb_split",
"wb16_to_wb32",
"wbgen2",
"wbgenplus",
]}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment