Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
P
Platform-independent core collection
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
18
Issues
18
List
Board
Labels
Milestones
Merge Requests
5
Merge Requests
5
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Platform-independent core collection
Commits
63f36713
Commit
63f36713
authored
Mar 26, 2020
by
Dimitris Lampridis
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'release/1.0.4'
parents
9e46223f
42b207a0
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
1966 additions
and
545 deletions
+1966
-545
CHANGELOG.rst
CHANGELOG.rst
+43
-12
README.md
README.md
+20
-2
Manifest.py
modules/axi/Manifest.py
+1
-0
Manifest.py
modules/axi/axi4lite32_axi4full64_bridge/Manifest.py
+3
-0
axi4lite32_axi4full64_bridge.vhd
...lite32_axi4full64_bridge/axi4lite32_axi4full64_bridge.vhd
+329
-0
Manifest.py
modules/common/Manifest.py
+6
-1
gc_enc_8b10b.vhd
modules/common/gc_enc_8b10b.vhd
+333
-0
gc_frequency_meter.vhd
modules/common/gc_frequency_meter.vhd
+15
-0
gc_negedge.vhd
modules/common/gc_negedge.vhd
+51
-0
gc_posedge.vhd
modules/common/gc_posedge.vhd
+51
-0
gc_pulse_synchronizer2.vhd
modules/common/gc_pulse_synchronizer2.vhd
+6
-0
gc_sync.vhd
modules/common/gc_sync.vhd
+104
-0
gc_sync_edge.vhd
modules/common/gc_sync_edge.vhd
+70
-0
gc_sync_ffs.vhd
modules/common/gc_sync_ffs.vhd
+30
-49
gc_sync_register.vhd
modules/common/gc_sync_register.vhd
+4
-1
gencores_pkg.vhd
modules/common/gencores_pkg.vhd
+156
-42
inferred_async_fifo.vhd
modules/genrams/common/inferred_async_fifo.vhd
+4
-0
inferred_async_fifo_dual_rst.vhd
modules/genrams/common/inferred_async_fifo_dual_rst.vhd
+4
-0
inferred_sync_fifo.vhd
modules/genrams/common/inferred_sync_fifo.vhd
+7
-7
genram_pkg.vhd
modules/genrams/genram_pkg.vhd
+5
-6
generic_dpram_dualclock.vhd
modules/genrams/xilinx/generic_dpram_dualclock.vhd
+3
-8
generic_dpram_sameclock.vhd
modules/genrams/xilinx/generic_dpram_sameclock.vhd
+0
-2
Manifest.py
modules/wishbone/Manifest.py
+1
-0
Manifest.py
modules/wishbone/wb16_to_wb32/Manifest.py
+1
-0
wb16_to_wb32.vhd
modules/wishbone/wb16_to_wb32/wb16_to_wb32.vhd
+119
-0
i2c_master_top.vhd
modules/wishbone/wb_i2c_master/i2c_master_top.vhd
+11
-11
wishbone_pkg.vhd
modules/wishbone/wishbone_pkg.vhd
+0
-3
if_wb_master.svh
sim/if_wb_master.svh
+268
-359
i2c-ocores.c
software/i2c-ocores/drivers/i2c/busses/i2c-ocores.c
+127
-40
tb.gtkw
testbench/wishbone/wb16_to_wb32/tb.gtkw
+51
-0
tb_wb16_to_wb32.vhd
testbench/wishbone/wb16_to_wb32/tb_wb16_to_wb32.vhd
+135
-0
gen_buildinfo.py
tools/gen_buildinfo.py
+8
-2
No files found.
CHANGELOG.rst
View file @
63f36713
..
SPDX-License-Identifier: CC
-BY-SA-4
.0
SPDX-License-Identifier: CC
0-1
.0
SPDX-FileCopyrightText: 2019 CERN
SPDX-FileCopyrightText: 2019
-2020
CERN
==========
Change Log
==========
Format: `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_
Versioning: `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_
- Format inspired by: `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_
- Versioning scheme follows: `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_
1.0.4 - 2020-03-26
==================
https://www.ohwr.org/project/general-cores/tags/v1.0.4
Added
-----
- [hdl] VHDL functions to convert characters and strings to upper/lower case.
- [sw][i2c] Support for kernel greater than 4.7.
- [hdl] Separate synchroniser and edge detection modules.
- [hdl] 8b10b encoder.
Changed
-------
- [hdl] Rewritten the WB master interface used in simulations.
- [hdl] Reimplement gc_sync_ffs using new synchroniser and edge detectors.
Fixed
-----
- [sw][spi] Align polarity and phase for Rx and Tx.
- [hdl][i2c] Fix reset lock for I2C master.
- [hdl] Avoid cyclic dependencies for log2 ceiling functions.
1.0.3 - 2020-01-15
==================
https://www.ohwr.org/project/general-cores/tags/v1.0.3
[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
==================
https://www.ohwr.org/project/general-cores/tags/v1.0.2
Fixed
-----
- [ci] forgot rule to publish RPMs
[1.0.1] - 2019-10-24
====================
1.0.1 - 2019-10-24
==================
https://www.ohwr.org/project/general-cores/tags/v1.0.1
Added
-----
- [ci] building and publish RPMs automatically on new releases
Changed
-------
- [sw] Makefiles have been changed to better support RPM generation
[1.0.0] - 2019-10-21
====================
1.0.0 - 2019-10-21
==================
https://www.ohwr.org/project/general-cores/tags/v1.0.0
Added
-----
- First release of general-cores.
README.md
View file @
63f36713
...
...
@@ -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/axi/Manifest.py
View file @
63f36713
modules
=
{
"local"
:
[
"z7_axi_gpio_expander"
,
"axi4lite_wb_bridge"
,
"axi4lite32_axi4full64_bridge"
,
]}
files
=
[
...
...
modules/axi/axi4lite32_axi4full64_bridge/Manifest.py
0 → 100644
View file @
63f36713
files
=
[
"axi4lite32_axi4full64_bridge.vhd"
,
];
modules/axi/axi4lite32_axi4full64_bridge/axi4lite32_axi4full64_bridge.vhd
0 → 100644
View file @
63f36713
-------------------------------------------------------------------------------
-- 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
;
modules/common/Manifest.py
View file @
63f36713
...
...
@@ -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"
,
...
...
modules/common/gc_enc_8b10b.vhd
0 → 100644
View file @
63f36713
--------------------------------------------------------------------------------
-- 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
;
modules/common/gc_frequency_meter.vhd
View file @
63f36713
...
...
@@ -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
;
...
...
modules/common/gc_negedge.vhd
0 → 100644
View file @
63f36713
--------------------------------------------------------------------------------
-- 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
;
modules/common/gc_posedge.vhd
0 → 100644
View file @
63f36713
--------------------------------------------------------------------------------
-- 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
;
modules/common/gc_pulse_synchronizer2.vhd
View file @
63f36713
...
...
@@ -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
;
...
...
modules/common/gc_sync.vhd
0 → 100644
View file @
63f36713
--------------------------------------------------------------------------------
-- 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
;
modules/common/gc_sync_edge.vhd
0 → 100644
View file @
63f36713
--------------------------------------------------------------------------------
-- 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
;
modules/common/gc_sync_ffs.vhd
View file @
63f36713
...
...
@@ -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
;
...
...
modules/common/gc_sync_register.vhd
View file @
63f36713
...
...
@@ -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"
;
...
...
modules/common/gencores_pkg.vhd
View file @
63f36713
...
...
@@ -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
;
modules/genrams/common/inferred_async_fifo.vhd
View file @
63f36713
...
...
@@ -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
;
...
...
modules/genrams/common/inferred_async_fifo_dual_rst.vhd
View file @
63f36713
...
...
@@ -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
;
...
...
modules/genrams/common/inferred_sync_fifo.vhd
View file @
63f36713
...
...
@@ -72,13 +72,13 @@ end inferred_sync_fifo;
architecture
syn
of
inferred_sync_fifo
is
constant
c_pointer_width
:
integer
:
=
f_log2_size
(
g_size
);
signal
rd_ptr
,
wr_ptr
,
wr_ptr_d0
,
rd_ptr_muxed
:
unsigned
(
c_pointer_width
-1
downto
0
);
signal
usedw
:
unsigned
(
c_pointer_width
downto
0
);
signal
full
,
empty
:
std_logic
;
signal
q_int
:
std_logic_vector
(
g_data_width
-1
downto
0
);
signal
we_int
,
rd_int
:
std_logic
;
signal
guard_bit
:
std_logic
;
constant
c_pointer_width
:
integer
:
=
f_log2_size
(
g_size
);
signal
rd_ptr
,
wr_ptr
,
rd_ptr_muxed
:
unsigned
(
c_pointer_width
-1
downto
0
);
signal
usedw
:
unsigned
(
c_pointer_width
downto
0
);
signal
full
,
empty
:
std_logic
;
signal
we_int
,
rd_int
:
std_logic
;
signal
guard_bit
:
std_logic
;
signal
q_comb
:
std_logic_vector
(
g_data_width
-1
downto
0
);
...
...
modules/genrams/genram_pkg.vhd
View file @
63f36713
...
...
@@ -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
...
...
modules/genrams/xilinx/generic_dpram_dualclock.vhd
View file @
63f36713
...
...
@@ -118,17 +118,12 @@ architecture syn of generic_dpram_dualclock is
return
false
;
-- synthesis translate_on
return
true
;
end
f_is_synthesis
;
end
f_is_synthesis
;
shared
variable
ram
:
t_ram_type
:
=
f_file_to_ramtype
;
signal
s_we_a
:
std_logic_vector
(
c_num_bytes
-1
downto
0
);
signal
s_ram_in_a
:
std_logic_vector
(
g_data_width
-1
downto
0
);
signal
s_we_b
:
std_logic_vector
(
c_num_bytes
-1
downto
0
);
signal
s_ram_in_b
:
std_logic_vector
(
g_data_width
-1
downto
0
);
signal
clka_int
:
std_logic
;
signal
clkb_int
:
std_logic
;
signal
wea_rep
,
web_rep
:
std_logic_vector
(
c_num_bytes
-1
downto
0
);
...
...
@@ -177,7 +172,7 @@ begin
end
loop
;
end
if
;
end
process
;
...
...
@@ -266,6 +261,6 @@ begin
end
if
;
end
process
;
end
generate
gen_without_byte_enable_nochange
;
end
syn
;
modules/genrams/xilinx/generic_dpram_sameclock.vhd
View file @
63f36713
...
...
@@ -123,9 +123,7 @@ architecture syn of generic_dpram_sameclock is
shared
variable
ram
:
t_ram_type
:
=
f_file_to_ramtype
;
signal
s_we_a
:
std_logic_vector
(
c_num_bytes
-1
downto
0
);
signal
s_ram_in_a
:
std_logic_vector
(
g_data_width
-1
downto
0
);
signal
s_we_b
:
std_logic_vector
(
c_num_bytes
-1
downto
0
);
signal
s_ram_in_b
:
std_logic_vector
(
g_data_width
-1
downto
0
);
signal
wea_rep
,
web_rep
:
std_logic_vector
(
c_num_bytes
-1
downto
0
);
...
...
modules/wishbone/Manifest.py
View file @
63f36713
...
...
@@ -26,6 +26,7 @@ modules = { "local" : [
"wb_ds182x_readout"
,
"wb_metadata"
,
"wb_split"
,
"wb16_to_wb32"
,
"wbgen2"
,
"wbgenplus"
,
]}
...
...
modules/wishbone/wb16_to_wb32/Manifest.py
0 → 100644
View file @
63f36713
files
=
[
"wb16_to_wb32.vhd"
]
modules/wishbone/wb16_to_wb32/wb16_to_wb32.vhd
0 → 100644
View file @
63f36713
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- WR2RF_VME core
-- https://ohwr.org/project/vme-rf-wr-bobr
--------------------------------------------------------------------------------
--
-- unit name: wb16_to_wb32
--
-- description: Bridge wishbone data width by using a register for the upper 16
-- bits.
-- In order to atomically read a 32 bit word at address ADDR:
-- * read the 16 LSB word at address ADDR
-- * read the 16 MSB word at address ADDR+2
-- In order to atomically write a 32 bit word at address ADDR:
-- * write the 16 MSB word at address ADDR+2
-- * write the 16 LSB word at address ADDR
--
--------------------------------------------------------------------------------
-- Copyright (c) 2019 CERN (home.cern)
--------------------------------------------------------------------------------
-- 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
work
.
wishbone_pkg
.
all
;
entity
wb16_to_wb32
is
port
(
clk_i
:
in
std_logic
;
rst_n_i
:
in
std_logic
;
wb16_i
:
in
t_wishbone_slave_in
;
wb16_o
:
out
t_wishbone_slave_out
;
wb32_i
:
in
t_wishbone_master_in
;
wb32_o
:
out
t_wishbone_master_out
);
end
;
architecture
arch
of
wb16_to_wb32
is
signal
datah
:
std_logic_vector
(
15
downto
0
);
signal
stall
:
std_logic
;
signal
we
:
std_logic
;
signal
ack
:
std_logic
;
begin
wb16_o
.
stall
<=
stall
or
ack
;
wb32_o
.
dat
(
31
downto
16
)
<=
datah
;
wb16_o
.
rty
<=
'0'
;
wb16_o
.
err
<=
'0'
;
wb16_o
.
ack
<=
ack
;
process
(
clk_i
)
is
begin
if
rising_edge
(
clk_i
)
then
if
rst_n_i
=
'0'
then
datah
<=
(
others
=>
'0'
);
stall
<=
'0'
;
ack
<=
'0'
;
wb32_o
.
cyc
<=
'0'
;
wb32_o
.
stb
<=
'0'
;
else
if
stall
=
'0'
then
-- Ready.
ack
<=
'0'
;
if
wb16_i
.
stb
=
'1'
and
wb16_i
.
cyc
=
'1'
and
ack
=
'0'
then
if
wb16_i
.
adr
(
1
)
=
'1'
then
-- Access to DATAH.
if
wb16_i
.
we
=
'1'
then
-- Write.
if
wb16_i
.
sel
(
0
)
=
'1'
then
datah
(
7
downto
0
)
<=
wb16_i
.
dat
(
7
downto
0
);
end
if
;
if
wb16_i
.
sel
(
1
)
=
'1'
then
datah
(
15
downto
8
)
<=
wb16_i
.
dat
(
15
downto
8
);
end
if
;
else
-- Read
wb16_o
.
dat
(
15
downto
0
)
<=
datah
;
end
if
;
ack
<=
'1'
;
else
-- Access to the device.
stall
<=
'1'
;
we
<=
wb16_i
.
we
;
wb32_o
.
cyc
<=
'1'
;
wb32_o
.
stb
<=
'1'
;
wb32_o
.
adr
<=
wb16_i
.
adr
(
31
downto
2
)
&
"00"
;
wb32_o
.
dat
(
15
downto
0
)
<=
wb16_i
.
dat
(
15
downto
0
);
wb32_o
.
we
<=
wb16_i
.
we
;
wb32_o
.
sel
<=
"11"
&
wb16_i
.
sel
(
1
downto
0
);
-- Humm...
end
if
;
end
if
;
else
-- Stall = 1, waiting for the answer.
if
wb32_i
.
ack
=
'1'
then
wb16_o
.
dat
(
15
downto
0
)
<=
wb32_i
.
dat
(
15
downto
0
);
if
we
=
'0'
then
datah
<=
wb32_i
.
dat
(
31
downto
16
);
end
if
;
wb32_o
.
cyc
<=
'0'
;
wb32_o
.
stb
<=
'0'
;
ack
<=
'1'
;
stall
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
if
;
end
process
;
end
arch
;
modules/wishbone/wb_i2c_master/i2c_master_top.vhd
View file @
63f36713
...
...
@@ -157,7 +157,7 @@ architecture structural of i2c_master_top is
signal
sr
:
std_logic_vector
(
7
downto
0
);
-- status register
-- internal reset signal
signal
rst_i
:
std_logic
;
signal
arst_n
:
std_logic
;
-- wishbone write access
signal
wb_wacc
:
std_logic
;
...
...
@@ -190,7 +190,7 @@ architecture structural of i2c_master_top is
begin
-- generate internal reset signal
rst_i
<=
not
wb_rst_i
;
--
arst_i xor ARST_LVL;
arst_n
<=
arst_i
xor
ARST_LVL
;
-- generate acknowledge output signal
gen_ack_o
:
process
(
wb_clk_i
)
...
...
@@ -228,9 +228,9 @@ begin
-- generate registers (CR, SR see below)
gen_regs
:
process
(
rst_i
,
wb_clk_i
)
gen_regs
:
process
(
arst_n
,
wb_clk_i
)
begin
if
(
rst_i
=
'0'
)
then
if
(
arst_n
=
'0'
)
then
prer
<=
(
others
=>
'1'
);
ctr
<=
(
others
=>
'0'
);
txr
<=
(
others
=>
'0'
);
...
...
@@ -268,9 +268,9 @@ begin
-- generate command register
gen_cr
:
process
(
rst_i
,
wb_clk_i
)
gen_cr
:
process
(
arst_n
,
wb_clk_i
)
begin
if
(
rst_i
=
'0'
)
then
if
(
arst_n
=
'0'
)
then
cr
<=
(
others
=>
'0'
);
elsif
(
wb_clk_i
'event
and
wb_clk_i
=
'1'
)
then
if
(
wb_rst_i
=
'1'
)
then
...
...
@@ -309,7 +309,7 @@ begin
port
map
(
clk
=>
wb_clk_i
,
rst
=>
wb_rst_i
,
nReset
=>
rst_i
,
nReset
=>
arst_n
,
ena
=>
core_en
,
clk_cnt
=>
prer
,
start
=>
sta
,
...
...
@@ -346,9 +346,9 @@ begin
st_irq_block
:
block
begin
-- generate status register bits
gen_sr_bits
:
process
(
wb_clk_i
,
rst
_i
)
gen_sr_bits
:
process
(
arst_n
,
wb_clk
_i
)
begin
if
(
rst_i
=
'0'
)
then
if
(
arst_n
=
'0'
)
then
al
<=
'0'
;
rxack
<=
'0'
;
tip
<=
'0'
;
...
...
@@ -371,9 +371,9 @@ begin
end
process
gen_sr_bits
;
-- generate interrupt request signals
gen_irq
:
process
(
wb_clk_i
,
rst
_i
)
gen_irq
:
process
(
arst_n
,
wb_clk
_i
)
begin
if
(
rst_i
=
'0'
)
then
if
(
arst_n
=
'0'
)
then
inta_o
<=
'0'
;
elsif
(
wb_clk_i
'event
and
wb_clk_i
=
'1'
)
then
if
(
wb_rst_i
=
'1'
)
then
...
...
modules/wishbone/wishbone_pkg.vhd
View file @
63f36713
...
...
@@ -28,9 +28,6 @@ library ieee;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
library
work
;
use
work
.
genram_pkg
.
all
;
package
wishbone_pkg
is
constant
c_wishbone_address_width
:
integer
:
=
32
;
...
...
sim/if_wb_master.svh
View file @
63f36713
//------------------------------------------------------------------------------
// CERN BE-CO-HT
// General Cores Library
// https://www.ohwr.org/projects/general-cores
//------------------------------------------------------------------------------
//
//
Title : Software Wishbone master unit for testbenches
//
unit name: IWishboneMaster
//
// File : if_wishbone.sv
// Author : Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
// Created : Tue Mar 23 12:19:36 2010
// Standard : SystemVerilog
// description: Software Wishbone master unit for testbenches.
//
/* Todo:
pipelined reads
settings wrapped in the accessor object
*/
//------------------------------------------------------------------------------
// Copyright CERN 2010-2019
//------------------------------------------------------------------------------
// 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.
//------------------------------------------------------------------------------
`include
"simdrv_defs.svh"
`include
"if_wishbone_types.svh"
...
...
@@ -23,35 +32,24 @@ interface IWishboneMaster
input
rst_n_i
)
;
parameter
g_addr_width
=
32
;
parameter
g_data_width
=
32
;
logic
[
g_addr_width
-
1
:
0
]
adr
;
logic
[
g_data_width
-
1
:
0
]
dat_o
;
logic
[(
g_data_width
/
8
)
-
1
:
0
]
sel
;
wire
[
g_data_width
-
1
:
0
]
dat_i
;
wire
ack
;
wire
stall
;
wire
err
;
wire
rty
;
logic
cyc
;
logic
stb
;
logic
we
;
wire
clk
;
wire
rst_n
;
time
last_access_t
=
0
;
parameter
g_addr_width
=
32
;
parameter
g_data_width
=
32
;
struct
{
int
gen_random_throttling
;
real
throttle_prob
;
int
little_endian
;
int
cyc_on_stall
;
wb_address_granularity_t
addr_gran
;
}
settings
;
logic
[
g_addr_width
-
1
:
0
]
adr
;
logic
[
g_data_width
-
1
:
0
]
dat_o
;
logic
[(
g_data_width
/
8
)
-
1
:
0
]
sel
;
wire
[
g_data_width
-
1
:
0
]
dat_i
;
wire
ack
;
wire
stall
;
wire
err
;
wire
rty
;
logic
cyc
;
logic
stb
;
logic
we
;
modport
master
wire
stall_valid
=
stall
&
cyc
;
modport
master
(
output
adr
,
output
dat_o
,
...
...
@@ -59,316 +57,246 @@ interface IWishboneMaster
output
cyc
,
output
stb
,
output
we
,
input
ack
,
input
dat_i
,
input
stall
,
input
err
,
input
rty
input
ack
,
input
dat_i
,
input
stall
,
input
err
,
input
rty
)
;
function
automatic
logic
[
g_addr_width
-
1
:
0
]
gen_addr
(
uint64_t
addr
,
int
xfer_size
)
;
if
(
settings
.
addr_gran
==
WORD
)
case
(
g_data_width
)
8
:
return
addr
;
16
:
return
addr
>>
1
;
32
:
return
addr
>>
2
;
64
:
return
addr
>>
3
;
default:
$
error
(
"IWishbone: invalid WB data bus width [%d bits
\n
]"
,
g_data_width
)
;
endcase
// case (xfer_size)
else
return
addr
;
endfunction
time
last_access_t
=
0
;
enum
{
IDLE
,
BUSY
,
WAIT_ACK
}
xf_state
;
wb_cycle_t
request_queue
[$]
;
wb_cycle_t
result_queue
[$]
;
struct
{
int
gen_random_throttling
;
real
throttle_prob
;
int
little_endian
;
// not supported
int
cyc_on_stall
;
// not used, kept for compatibility
wb_address_granularity_t
addr_gran
;
}
settings
;
function
automatic
logic
[
63
:
0
]
rev_bits
(
logic
[
63
:
0
]
x
,
int
nbits
)
;
logic
[
63
:
0
]
tmp
;
int
i
;
for
(
i
=
0
;
i
<
nbits
;
i
++
)
tmp
[
nbits
-
1
-
i
]
=
x
[
i
]
;
for
(
i
=
0
;
i
<
nbits
;
i
++
)
tmp
[
nbits
-
1
-
i
]
=
x
[
i
]
;
return
tmp
;
endfunction
// rev_bits
function
automatic
logic
[
g_addr_width
-
1
:
0
]
gen_addr
(
wb_xfer_t
xfer
)
;
if
(
settings
.
addr_gran
==
WORD
)
case
(
g_data_width
)
8
:
return
xfer
.
a
;
16
:
return
xfer
.
a
>>
1
;
32
:
return
xfer
.
a
>>
2
;
64
:
return
xfer
.
a
>>
3
;
default:
$
error
(
"IWishbone: invalid WB data bus width [%d bits
\n
]"
,
g_data_width
)
;
endcase
else
return
xfer
.
a
;
endfunction
// gen_addr
//FIXME: little endian
function
automatic
logic
[(
g_data_width
/
8
)
-
1
:
0
]
gen_sel
(
uint64_t
addr
,
int
xfer_size
,
int
little_endian
)
;
function
automatic
logic
[(
g_data_width
/
8
)
-
1
:
0
]
gen_sel
(
wb_xfer_t
xfer
)
;
logic
[(
g_data_width
/
8
)
-
1
:
0
]
sel
;
const
int
dbytes
=
(
g_data_width
/
8
-
1
)
;
sel
=
((
1
<<
xfer_size
)
-
1
)
;
return
rev_bits
(
sel
<<
(
addr
%
xfer_size
)
,
g_data_width
/
8
)
;
endfunction
sel
=
((
1
<<
xfer
.
size
)
-
1
)
;
return
rev_bits
(
sel
<<
(
xfer
.
a
%
xfer
.
size
)
,
g_data_width
/
8
)
;
endfunction
// gen_sel
function
automatic
logic
[
g_data_width
-
1
:
0
]
gen_data
(
uint64_t
addr
,
uint64_t
data
,
int
xfer_size
,
int
little_endian
)
;
//FIXME: little endian
function
automatic
logic
[
g_data_width
-
1
:
0
]
gen_data
(
wb_xfer_t
xfer
)
;
const
int
dbytes
=
(
g_data_width
/
8
-
1
)
;
logic
[
g_data_width
-
1
:
0
]
tmp
;
tmp
=
data
<<
(
8
*
(
dbytes
-
(
xfer_size
-
1
-
(
addr
%
xfer_size
))))
;
// $display("GenData: xs %d dbytes %d %x", tmp, xfer_size, dbytes);
return
tmp
;
return
xfer
.
d
<<
(
8
*
(
dbytes
-
(
xfer
.
size
-
1
-
(
xfer
.
a
%
xfer
.
size
))))
;
endfunction
// gen_data
function
automatic
uint64_t
decode_data
(
uint64_t
addr
,
logic
[
g_data_width
-
1
:
0
]
data
,
int
xfer_size
)
;
function
automatic
uint64_t
decode_data
(
wb_xfer_t
xfer
,
logic
[
g_data_width
-
1
:
0
]
data
)
;
int
rem
;
// $display("decode: a %x d %x xs %x", addr, data ,xfer_size);
rem
=
xfer
.
a
%
xfer
.
size
;
rem
=
addr
%
xfer_size
;
return
(
data
>>
(
8
*
rem
))
&
((
1
<<
(
xfer_size
*
8
))
-
1
)
;
return
(
data
>>
(
8
*
rem
))
&
((
1
<<
(
xfer
.
size
*
8
))
-
1
)
;
endfunction
// decode_data
task
automatic
classic_cycle
(
inout
wb_xfer_t
xfer
[]
,
input
bit
rw
,
input
int
n_xfers
,
output
wb_cycle_result_t
result
)
;
int
i
;
if
($
time
!=
last_access_t
)
@
(
posedge
clk_i
)
;
/* resynchronize, just in case */
for
(
i
=
0
;
i
<
n_xfers
;
i
++
)
begin
stb
<=
1'b1
;
cyc
<=
1'b1
;
adr
<=
gen_addr
(
xfer
[
i
]
.
a
,
xfer
[
i
]
.
size
)
;
we
<=
rw
;
sel
<=
gen_sel
(
xfer
[
i
]
.
a
,
xfer
[
i
]
.
size
,
settings
.
little_endian
)
;
//gen_sel(xfer[i].a, xfer[i].size);
dat_o
<=
gen_data
(
xfer
[
i
]
.
a
,
xfer
[
i
]
.
d
,
xfer
[
i
]
.
size
,
settings
.
little_endian
)
;
@
(
posedge
clk_i
)
;
if
(
ack
==
0
)
begin
while
(
ack
==
0
)
begin
@
(
posedge
clk_i
)
;
end
end
else
if
(
err
==
1'b1
||
rty
==
1'b1
)
begin
cyc
<=
0
;
we
<=
0
;
stb
<=
0
;
result
=
(
err
==
1'b1
?
R_ERROR
:
R_RETRY
)
;
break
;
end
xfer
[
i
]
.
d
=
decode_data
(
xfer
[
i
]
.
a
,
dat_i
,
xfer
[
i
]
.
size
)
;
cyc
<=
0
;
we
<=
0
;
stb
<=
0
;
end
// if (ack == 0)
@
(
posedge
clk_i
)
;
result
=
R_OK
;
last_access_t
=
$
time
;
endtask
// automatic
task
automatic
classic_cycle
(
ref
wb_cycle_t
c
)
;
reg
xf_idle
=
1
;
int
i
;
int
ack_cnt_int
;
int
failure
=
0
;
/* resynchronize, just in case */
if
($
time
!=
last_access_t
)
@
(
posedge
clk_i
)
;
xf_state
=
BUSY
;
for
(
i
=
0
;
i
<
c
.
data
.
size
()
;
i
++
)
begin
stb
<=
1'b1
;
cyc
<=
1'b1
;
adr
<=
gen_addr
(
c
.
data
[
i
])
;
we
<=
(
c
.
rw
!=
0
)
;
sel
<=
gen_sel
(
c
.
data
[
i
])
;
dat_o
<=
gen_data
(
c
.
data
[
i
])
;
@
(
posedge
clk_i
)
;
while
(
ack
!=
1'b1
&&
err
!=
1'b1
&&
rty
==
1'b1
)
@
(
posedge
clk_i
)
;
if
(
err
||
rty
)
begin
c
.
result
=
(
err
?
R_ERROR
:
R_RETRY
)
;
failure
=
1
;
break
;
end
c
.
data
[
i
]
.
d
=
decode_data
(
c
.
data
[
i
]
,
dat_i
)
;
cyc
<=
0
;
we
<=
0
;
stb
<=
0
;
@
(
posedge
clk_i
)
;
end
if
(
!
failure
)
c
.
result
=
R_OK
;
xf_state
=
IDLE
;
last_access_t
=
$
time
;
endtask
// classic_cycle
task
automatic
pipelined_cycle
(
ref
wb_cycle_t
c
)
;
int
stb_count
=
0
;
int
ack_count
=
0
;
int
failure
=
0
;
int
cur_rdbk
=
0
;
/* resynchronize, just in case */
if
($
time
!=
last_access_t
)
@
(
posedge
clk_i
)
;
xf_state
=
BUSY
;
cyc
<=
1'b1
;
stb
<=
1'b1
;
adr
<=
gen_addr
(
c
.
data
[
stb_count
])
;
if
(
c
.
rw
==
1
)
begin
we
<=
1'b1
;
sel
<=
gen_sel
(
c
.
data
[
stb_count
])
;
dat_o
<=
gen_data
(
c
.
data
[
stb_count
])
;
end
else
begin
we
<=
1'b0
;
sel
<=
'hffffffff
;
end
while
(
stall_valid
||
((
stb_count
<
c
.
data
.
size
())
&&
!
failure
))
begin
if
(
ack
)
begin
ack_count
++;
if
(
c
.
rw
==
0
)
begin
c
.
data
[
cur_rdbk
]
.
d
=
dat_i
;
cur_rdbk
++;
end
end
else
if
(
err
||
rty
)
begin
c
.
result
=
(
err
?
R_ERROR
:
R_RETRY
)
;
failure
=
1
;
break
;
end
if
(
settings
.
gen_random_throttling
&&
probability_hit
(
settings
.
throttle_prob
))
begin
stb
<=
1'b0
;
we
<=
1'b0
;
end
else
if
(
stall_valid
==
1'b0
)
begin
stb
<=
1'b1
;
adr
<=
gen_addr
(
c
.
data
[
stb_count
])
;
if
(
c
.
rw
==
1
)
begin
we
<=
1'b1
;
sel
<=
gen_sel
(
c
.
data
[
stb_count
])
;
dat_o
<=
gen_data
(
c
.
data
[
stb_count
])
;
end
else
begin
we
<=
1'b0
;
sel
<=
'hffffffff
;
end
stb_count
++;
end
@
(
posedge
clk_i
)
;
end
stb
<=
1'b0
;
we
<=
1'b0
;
xf_state
=
WAIT_ACK
;
while
((
ack_count
<
c
.
data
.
size
())
&&
!
failure
)
begin
if
(
ack
)
begin
ack_count
++;
if
(
c
.
rw
==
0
)
begin
c
.
data
[
cur_rdbk
]
.
d
=
dat_i
;
cur_rdbk
++;
end
end
else
if
(
err
||
rty
)
begin
c
.
result
=
(
err
?
R_ERROR
:
R_RETRY
)
;
failure
=
1
;
xf_state
=
IDLE
;
break
;
end
if
(
ack_count
==
c
.
data
.
size
())
begin
cyc
<=
1'b0
;
we
<=
1'b0
;
xf_state
=
IDLE
;
end
@
(
posedge
clk_i
)
;
end
always
@
(
posedge
clk_i
)
begin
if
(
!
cyc
)
ack_cnt_int
<=
0
;
else
if
(
stb
&&
!
stall
&&
!
ack
)
ack_cnt_int
++;
else
if
((
!
stb
||
stall
)
&&
ack
)
ack_cnt_int
--;
end
task
automatic
count_ack
(
ref
int
ack_cnt
)
;
// if(stb && !stall && !ack)
// ack_cnt++;
if
(
ack
)
ack_cnt
--;
endtask
task
automatic
handle_readback
(
ref
wb_xfer_t
xf
[$]
,
input
int
read
,
ref
int
cur_rdbk
)
;
if
(
ack
&&
read
)
begin
xf
[
cur_rdbk
]
.
d
=
dat_i
;
cur_rdbk
++;
end
endtask
// handle_readback
task
automatic
pipelined_cycle
(
ref
wb_xfer_t
xfer
[$]
,
input
int
write
,
input
int
n_xfers
,
output
wb_cycle_result_t
result
)
;
int
i
;
int
ack_count
;
int
failure
;
int
cur_rdbk
;
ack_count
=
0
;
failure
=
0
;
xf_idle
=
0
;
cur_rdbk
=
0
;
if
($
time
!=
last_access_t
)
@
(
posedge
clk_i
)
;
/* resynchronize, just in case */
while
(
stall
&&
!
settings
.
cyc_on_stall
)
@
(
posedge
clk_i
)
;
cyc
<=
1'b1
;
i
=
0
;
ack_count
=
n_xfers
;
while
(
i
<
n_xfers
)
begin
count_ack
(
ack_count
)
;
handle_readback
(
xfer
,
!
write
,
cur_rdbk
)
;
if
(
err
)
begin
result
=
R_ERROR
;
failure
=
1
;
break
;
end
if
(
rty
)
begin
result
=
R_RETRY
;
failure
=
1
;
break
;
end
if
(
!
stall
&&
settings
.
gen_random_throttling
&&
probability_hit
(
settings
.
throttle_prob
))
begin
stb
<=
1'b0
;
we
<=
1'b0
;
@
(
posedge
clk_i
)
;
end
else
begin
adr
<=
gen_addr
(
xfer
[
i
]
.
a
,
xfer
[
i
]
.
size
)
;
stb
<=
1'b1
;
if
(
write
)
begin
we
<=
1'b1
;
sel
<=
gen_sel
(
xfer
[
i
]
.
a
,
xfer
[
i
]
.
size
,
settings
.
little_endian
)
;
dat_o
<=
gen_data
(
xfer
[
i
]
.
a
,
xfer
[
i
]
.
d
,
xfer
[
i
]
.
size
,
settings
.
little_endian
)
;
end
else
begin
we
<=
1'b0
;
sel
<=
'hffffffff
;
end
@
(
posedge
clk_i
)
;
stb
<=
1'b0
;
we
<=
1'b0
;
if
(
stall
)
begin
stb
<=
1'b1
;
if
(
write
)
we
<=
1'b1
;
while
(
stall
)
begin
count_ack
(
ack_count
)
;
@
(
posedge
clk_i
)
;
end
stb
<=
1'b0
;
we
<=
1'b0
;
end
i
++;
end
end
// for (i =0;i<n_xfers;i++)
while
((
ack_count
>
0
)
&&
!
failure
)
begin
// $display("AckCount %d", ack_count);
if
(
err
)
begin
result
=
R_ERROR
;
failure
=
1
;
break
;
end
if
(
rty
)
begin
result
=
R_RETRY
;
failure
=
1
;
break
;
end
count_ack
(
ack_count
)
;
handle_readback
(
xfer
,
!
write
,
cur_rdbk
)
;
if
(
stb
&&
!
ack
)
ack_count
++;
else
if
(
!
stb
&&
ack
)
ack_count
--;
@
(
posedge
clk_i
)
;
end
cyc
<=
1'b0
;
@
(
posedge
clk_i
)
;
if
(
!
failure
)
result
=
R_OK
;
xf_idle
=
1
;
last_access_t
=
$
time
;
endtask
// automatic
we
<=
1'b0
;
wb_cycle_t
request_queue
[$]
;
wb_cycle_t
result_queue
[$]
;
if
(
!
failure
)
c
.
result
=
R_OK
;
last_access_t
=
$
time
;
endtask
// pipelined_cycle
class
CIWBMasterAccessor
extends
CWishboneAccessor
;
function
automatic
int
poll
()
;
return
0
;
endfunction
endfunction
// poll
task
get
(
ref
wb_cycle_t
xfer
)
;
while
(
!
result_queue
.
size
())
@
(
posedge
clk_i
)
;
xfer
=
result_queue
.
pop_front
()
;
endtask
task
clear
()
;
endtask
// clear
@
(
posedge
clk_i
)
;
xfer
=
result_queue
.
pop_front
()
;
endtask
// get
task
put
(
ref
wb_cycle_t
xfer
)
;
request_queue
.
push_back
(
xfer
)
;
endtask
// put
function
int
idle
()
;
return
(
request_queue
.
size
()
==
0
)
&&
xf_idle
;
return
(
request_queue
.
size
()
==
0
)
&&
(
xf_state
==
IDLE
)
;
endfunction
// idle
endclass
// CIWBMasterAccessor
endclass
// CIWBMasterAccessor
function
automatic
CIWBMasterAccessor
get_accessor
()
;
automatic
CIWBMasterAccessor
tmp
;
...
...
@@ -376,63 +304,44 @@ endclass // CIWBMasterAccessor
return
tmp
;
endfunction
// get_accessor
always
@
(
posedge
clk_i
)
if
(
!
rst_n_i
)
begin
request_queue
=
{};
result_queue
=
{};
xf_idle
=
1
;
cyc
<=
0
;
dat_o
<=
0
;
stb
<=
0
;
sel
<=
0
;
adr
<=
0
;
we
<=
0
;
end
if
(
!
rst_n_i
)
begin
request_queue
=
{};
result_queue
=
{};
xf_state
=
IDLE
;
cyc
<=
0
;
dat_o
<=
0
;
stb
<=
0
;
sel
<=
0
;
adr
<=
0
;
we
<=
0
;
end
initial
begin
settings
.
gen_random_throttling
=
0
;
settings
.
throttle_prob
=
0.1
;
settings
.
cyc_on_stall
=
0
;
settings
.
addr_gran
=
WORD
;
settings
.
throttle_prob
=
0.1
;
settings
.
addr_gran
=
WORD
;
end
initial
forever
begin
@
(
posedge
clk_i
)
;
if
(
request_queue
.
size
()
>
0
)
begin
wb_cycle_t
c
;
c
=
request_queue
.
pop_front
()
;
case
(
c
.
ctype
)
PIPELINED:
pipelined_cycle
(
c
)
;
CLASSIC:
classic_cycle
(
c
)
;
endcase
result_queue
.
push_back
(
c
)
;
end
end
initial
forever
begin
@
(
posedge
clk_i
)
;
if
(
request_queue
.
size
()
>
0
)
begin
wb_cycle_t
c
;
wb_cycle_result_t
res
;
c
=
request_queue
.
pop_front
()
;
case
(
c
.
ctype
)
PIPELINED:
begin
pipelined_cycle
(
c
.
data
,
c
.
rw
,
c
.
data
.
size
()
,
res
)
;
c
.
result
=
res
;
end
CLASSIC:
begin
// $display("WBMaster: got classic cycle [%d, rw %d]", c.data.size(), c.rw);
classic_cycle
(
c
.
data
,
c
.
rw
,
c
.
data
.
size
,
res
)
;
c
.
result
=
res
;
end
endcase
// case (c.ctype)
result_queue
.
push_back
(
c
)
;
end
end
endinterface
// IWishbone
endinterface
// IWishboneMaster
software/i2c-ocores/drivers/i2c/busses/i2c-ocores.c
View file @
63f36713
...
...
@@ -28,6 +28,91 @@
#include <linux/spinlock.h>
#include <linux/jiffies.h>
struct
ocores_i2c
;
static
int
ohwr_i2c_mux_select
(
struct
ocores_i2c
*
i2c
,
u32
num
);
static
int
ohwr_i2c_mux_deselect
(
struct
ocores_i2c
*
i2c
,
u32
num
);
#if KERNEL_VERSION(4, 7, 0) > LINUX_VERSION_CODE
struct
i2c_mux_core
{
struct
i2c_adapter
*
parent
;
struct
device
*
dev
;
void
*
priv
;
unsigned
int
max_adapters
;
struct
i2c_adapter
*
adapter
[
0
];
};
/**
* It selects the I2C bus to use and lock it
*/
static
int
ocores_i2c_mux_select_old_api
(
struct
i2c_adapter
*
adap
,
void
*
priv
,
u32
num
)
{
struct
ocores_i2c
*
i2c
=
priv
;
return
ohwr_i2c_mux_select
(
i2c
,
num
);
}
/**
* It unlocks the bus so that it can be changed.
*/
static
int
ocores_i2c_mux_deselect_old_api
(
struct
i2c_adapter
*
adap
,
void
*
priv
,
u32
num
)
{
struct
ocores_i2c
*
i2c
=
priv
;
return
ohwr_i2c_mux_deselect
(
i2c
,
num
);
}
struct
i2c_mux_core
*
i2c_mux_alloc
(
struct
i2c_adapter
*
parent
,
struct
device
*
dev
,
int
max_adapters
,
int
sizeof_priv
,
u32
flags
,
int
(
*
select
)(
struct
i2c_mux_core
*
,
u32
),
int
(
*
deselect
)(
struct
i2c_mux_core
*
,
u32
))
{
struct
i2c_mux_core
*
muxc
;
muxc
=
devm_kzalloc
(
dev
,
sizeof
(
*
muxc
)
+
sizeof
(
*
muxc
->
adapter
)
*
max_adapters
+
sizeof_priv
,
GFP_KERNEL
);
if
(
!
muxc
)
return
NULL
;
if
(
sizeof_priv
)
muxc
->
priv
=
&
muxc
->
adapter
[
max_adapters
];
muxc
->
parent
=
parent
;
muxc
->
dev
=
dev
;
muxc
->
max_adapters
=
max_adapters
;
return
muxc
;
}
int
i2c_mux_add_adapter
(
struct
i2c_mux_core
*
muxc
,
u32
force_nr
,
u32
chan_id
,
unsigned
int
class
)
{
muxc
->
adapter
[
chan_id
]
=
i2c_add_mux_adapter
(
muxc
->
parent
,
muxc
->
dev
,
muxc
->
priv
,
force_nr
,
chan_id
,
#if KERNEL_VERSION(3, 7, 0) <= LINUX_VERSION_CODE
class
,
/* class */
#endif
ocores_i2c_mux_select_old_api
,
ocores_i2c_mux_deselect_old_api
);
return
muxc
->
adapter
[
chan_id
]
?
0
:
-
EINVAL
;
}
void
i2c_mux_del_adapters
(
struct
i2c_mux_core
*
muxc
)
{
int
i
;
for
(
i
=
0
;
i
<
muxc
->
max_adapters
;
++
i
)
i2c_del_mux_adapter
(
muxc
->
adapter
[
i
]);
}
#endif
#define OCORES_FLAG_POLL BIT(0)
/**
...
...
@@ -41,8 +126,7 @@ struct ocores_i2c {
unsigned
long
flags
;
wait_queue_head_t
wait
;
struct
i2c_adapter
adap
;
struct
i2c_adapter
**
adap_mux
;
unsigned
int
n_adap_mux
;
struct
i2c_mux_core
*
adap_mux
;
struct
i2c_msg
*
msg
;
int
pos
;
int
nmsgs
;
...
...
@@ -578,14 +662,8 @@ static const struct platform_device_id ocores_id_table[] = {
};
MODULE_DEVICE_TABLE
(
id_table
,
ocores_id_table
);
/**
* It selects the I2C bus to use and lock it
*/
static
int
ocores_i2c_mux_select
(
struct
i2c_adapter
*
adap
,
void
*
priv
,
u32
num
)
static
int
ohwr_i2c_mux_select
(
struct
ocores_i2c
*
i2c
,
u32
num
)
{
struct
ocores_i2c
*
i2c
=
priv
;
u8
mux
;
mux
=
oc_getreg
(
i2c
,
OCI2C_OHWR_MUX
);
...
...
@@ -601,57 +679,69 @@ static int ocores_i2c_mux_select(struct i2c_adapter *adap,
return
0
;
}
/**
* It unlocks the bus so that it can be changed.
*/
static
int
ocores_i2c_mux_deselect
(
struct
i2c_adapter
*
adap
,
void
*
priv
,
u32
num
)
static
int
ohwr_i2c_mux_deselect
(
struct
ocores_i2c
*
i2c
,
u32
num
)
{
struct
ocores_i2c
*
i2c
=
priv
;
u8
mux
;
/* Unlock bus selection */
mux
=
oc_getreg
(
i2c
,
OCI2C_OHWR_MUX
);
if
(
unlikely
(
!
(
mux
&
OCI2C_OHWR_MUX_BUSY
)))
dev_err
(
&
adap
->
dev
,
"deselect a bus that was not selected
\n
"
);
dev_err
(
i2c
->
adap_mux
->
dev
,
"deselect a bus that was not selected
\n
"
);
mux
&=
~
OCI2C_OHWR_MUX_BUSY
;
oc_setreg
(
i2c
,
OCI2C_OHWR_MUX
,
mux
);
return
0
;
}
/**
* It selects the I2C bus to use and lock it
*/
static
int
ocores_i2c_mux_select
(
struct
i2c_mux_core
*
muxc
,
u32
num
)
{
struct
ocores_i2c
*
i2c
=
muxc
->
priv
;
return
ohwr_i2c_mux_select
(
i2c
,
num
);
}
/**
* It unlocks the bus so that it can be changed.
*/
static
int
ocores_i2c_mux_deselect
(
struct
i2c_mux_core
*
muxc
,
u32
num
)
{
struct
ocores_i2c
*
i2c
=
muxc
->
priv
;
return
ohwr_i2c_mux_deselect
(
i2c
,
num
);
}
/**
* Add OHWR multiplexer
*/
static
int
ocores_i2c_probe_ohwr
(
struct
ocores_i2c
*
i2c
)
{
int
err
,
i
;
i2c
->
n_adap_mux
=
2
;
i2c
->
adap_mux
=
devm_kzalloc
(
&
i2c
->
adap
.
dev
,
sizeof
(
void
*
)
*
i2c
->
n_adap_mux
,
GFP_KERNEL
);
for
(
i
=
0
;
i
<
i2c
->
n_adap_mux
;
++
i
)
{
i2c
->
adap_mux
[
i
]
=
i2c_add_mux_adapter
(
&
i2c
->
adap
,
i2c
->
adap
.
dev
.
parent
,
i2c
,
0
,
i
,
#if KERNEL_VERSION(3, 7, 0) <= LINUX_VERSION_CODE
0
,
/* class */
#endif
ocores_i2c_mux_select
,
ocores_i2c_mux_deselect
);
if
(
!
i2c
->
adap_mux
[
i
])
int
i
,
err
=
0
;
i2c
->
adap_mux
=
i2c_mux_alloc
(
&
i2c
->
adap
,
i2c
->
adap
.
dev
.
parent
,
2
,
sizeof
(
i2c
),
0
,
ocores_i2c_mux_select
,
ocores_i2c_mux_deselect
);
if
(
!
i2c
->
adap_mux
)
{
err
=
-
ENOMEM
;
goto
err_exit
;
}
i2c
->
adap_mux
->
priv
=
i2c
;
for
(
i
=
0
;
i
<
i2c
->
adap_mux
->
max_adapters
;
++
i
)
{
err
=
i2c_mux_add_adapter
(
i2c
->
adap_mux
,
0
,
i
,
0
);
if
(
err
)
goto
err_add
;
}
return
0
;
err_add:
while
(
--
i
>=
0
)
i2c_del_mux_adapter
(
i2c
->
adap_mux
[
i
]);
i2c_mux_del_adapters
(
i2c
->
adap_mux
);
err_exit:
return
err
;
}
...
...
@@ -660,10 +750,7 @@ err_add:
*/
static
void
ocores_i2c_remove_ohwr
(
struct
ocores_i2c
*
i2c
)
{
int
i
;
for
(
i
=
0
;
i
<
i2c
->
n_adap_mux
;
++
i
)
i2c_del_mux_adapter
(
i2c
->
adap_mux
[
i
]);
i2c_mux_del_adapters
(
i2c
->
adap_mux
);
}
#ifdef CONFIG_OF
...
...
testbench/wishbone/wb16_to_wb32/tb.gtkw
0 → 100644
View file @
63f36713
[*]
[*] GTKWave Analyzer v3.3.98 (w)1999-2018 BSI
[*] Tue Mar 3 12:42:41 2020
[*]
[dumpfile] "/home/tgingold/Repositories/ohwr/general-cores/modules/wishbone/wb16_to_wb32/tb/tb.ghw"
[dumpfile_mtime] "Tue Mar 3 12:40:34 2020"
[dumpfile_size] 2363
[savefile] "/home/tgingold/Repositories/ohwr/general-cores/modules/wishbone/wb16_to_wb32/tb/tb.gtkw"
[timestart] 0
[size] 1620 1056
[pos] -1 -1
*-23.629396 61240000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] top.
[treeopen] top.tb_wb16_to_wb32.
[sst_width] 283
[signals_width] 102
[sst_expanded] 1
[sst_vpaned_height] 315
@28
top.tb_wb16_to_wb32.rst_n
top.tb_wb16_to_wb32.clk
@200
-wb32
@28
top.tb_wb16_to_wb32.wb32_in.cyc
top.tb_wb16_to_wb32.wb32_in.stb
top.tb_wb16_to_wb32.wb32_in.we
top.tb_wb16_to_wb32.wb32_out.ack
@22
#{top.tb_wb16_to_wb32.wb32_out.dat[31:0]} top.tb_wb16_to_wb32.wb32_out.dat[31] top.tb_wb16_to_wb32.wb32_out.dat[30] top.tb_wb16_to_wb32.wb32_out.dat[29] top.tb_wb16_to_wb32.wb32_out.dat[28] top.tb_wb16_to_wb32.wb32_out.dat[27] top.tb_wb16_to_wb32.wb32_out.dat[26] top.tb_wb16_to_wb32.wb32_out.dat[25] top.tb_wb16_to_wb32.wb32_out.dat[24] top.tb_wb16_to_wb32.wb32_out.dat[23] top.tb_wb16_to_wb32.wb32_out.dat[22] top.tb_wb16_to_wb32.wb32_out.dat[21] top.tb_wb16_to_wb32.wb32_out.dat[20] top.tb_wb16_to_wb32.wb32_out.dat[19] top.tb_wb16_to_wb32.wb32_out.dat[18] top.tb_wb16_to_wb32.wb32_out.dat[17] top.tb_wb16_to_wb32.wb32_out.dat[16] top.tb_wb16_to_wb32.wb32_out.dat[15] top.tb_wb16_to_wb32.wb32_out.dat[14] top.tb_wb16_to_wb32.wb32_out.dat[13] top.tb_wb16_to_wb32.wb32_out.dat[12] top.tb_wb16_to_wb32.wb32_out.dat[11] top.tb_wb16_to_wb32.wb32_out.dat[10] top.tb_wb16_to_wb32.wb32_out.dat[9] top.tb_wb16_to_wb32.wb32_out.dat[8] top.tb_wb16_to_wb32.wb32_out.dat[7] top.tb_wb16_to_wb32.wb32_out.dat[6] top.tb_wb16_to_wb32.wb32_out.dat[5] top.tb_wb16_to_wb32.wb32_out.dat[4] top.tb_wb16_to_wb32.wb32_out.dat[3] top.tb_wb16_to_wb32.wb32_out.dat[2] top.tb_wb16_to_wb32.wb32_out.dat[1] top.tb_wb16_to_wb32.wb32_out.dat[0]
#{top.tb_wb16_to_wb32.wb32_in.adr[31:0]} top.tb_wb16_to_wb32.wb32_in.adr[31] top.tb_wb16_to_wb32.wb32_in.adr[30] top.tb_wb16_to_wb32.wb32_in.adr[29] top.tb_wb16_to_wb32.wb32_in.adr[28] top.tb_wb16_to_wb32.wb32_in.adr[27] top.tb_wb16_to_wb32.wb32_in.adr[26] top.tb_wb16_to_wb32.wb32_in.adr[25] top.tb_wb16_to_wb32.wb32_in.adr[24] top.tb_wb16_to_wb32.wb32_in.adr[23] top.tb_wb16_to_wb32.wb32_in.adr[22] top.tb_wb16_to_wb32.wb32_in.adr[21] top.tb_wb16_to_wb32.wb32_in.adr[20] top.tb_wb16_to_wb32.wb32_in.adr[19] top.tb_wb16_to_wb32.wb32_in.adr[18] top.tb_wb16_to_wb32.wb32_in.adr[17] top.tb_wb16_to_wb32.wb32_in.adr[16] top.tb_wb16_to_wb32.wb32_in.adr[15] top.tb_wb16_to_wb32.wb32_in.adr[14] top.tb_wb16_to_wb32.wb32_in.adr[13] top.tb_wb16_to_wb32.wb32_in.adr[12] top.tb_wb16_to_wb32.wb32_in.adr[11] top.tb_wb16_to_wb32.wb32_in.adr[10] top.tb_wb16_to_wb32.wb32_in.adr[9] top.tb_wb16_to_wb32.wb32_in.adr[8] top.tb_wb16_to_wb32.wb32_in.adr[7] top.tb_wb16_to_wb32.wb32_in.adr[6] top.tb_wb16_to_wb32.wb32_in.adr[5] top.tb_wb16_to_wb32.wb32_in.adr[4] top.tb_wb16_to_wb32.wb32_in.adr[3] top.tb_wb16_to_wb32.wb32_in.adr[2] top.tb_wb16_to_wb32.wb32_in.adr[1] top.tb_wb16_to_wb32.wb32_in.adr[0]
#{top.tb_wb16_to_wb32.wb32_in.dat[31:0]} top.tb_wb16_to_wb32.wb32_in.dat[31] top.tb_wb16_to_wb32.wb32_in.dat[30] top.tb_wb16_to_wb32.wb32_in.dat[29] top.tb_wb16_to_wb32.wb32_in.dat[28] top.tb_wb16_to_wb32.wb32_in.dat[27] top.tb_wb16_to_wb32.wb32_in.dat[26] top.tb_wb16_to_wb32.wb32_in.dat[25] top.tb_wb16_to_wb32.wb32_in.dat[24] top.tb_wb16_to_wb32.wb32_in.dat[23] top.tb_wb16_to_wb32.wb32_in.dat[22] top.tb_wb16_to_wb32.wb32_in.dat[21] top.tb_wb16_to_wb32.wb32_in.dat[20] top.tb_wb16_to_wb32.wb32_in.dat[19] top.tb_wb16_to_wb32.wb32_in.dat[18] top.tb_wb16_to_wb32.wb32_in.dat[17] top.tb_wb16_to_wb32.wb32_in.dat[16] top.tb_wb16_to_wb32.wb32_in.dat[15] top.tb_wb16_to_wb32.wb32_in.dat[14] top.tb_wb16_to_wb32.wb32_in.dat[13] top.tb_wb16_to_wb32.wb32_in.dat[12] top.tb_wb16_to_wb32.wb32_in.dat[11] top.tb_wb16_to_wb32.wb32_in.dat[10] top.tb_wb16_to_wb32.wb32_in.dat[9] top.tb_wb16_to_wb32.wb32_in.dat[8] top.tb_wb16_to_wb32.wb32_in.dat[7] top.tb_wb16_to_wb32.wb32_in.dat[6] top.tb_wb16_to_wb32.wb32_in.dat[5] top.tb_wb16_to_wb32.wb32_in.dat[4] top.tb_wb16_to_wb32.wb32_in.dat[3] top.tb_wb16_to_wb32.wb32_in.dat[2] top.tb_wb16_to_wb32.wb32_in.dat[1] top.tb_wb16_to_wb32.wb32_in.dat[0]
#{top.tb_wb16_to_wb32.wb32_in.sel[3:0]} top.tb_wb16_to_wb32.wb32_in.sel[3] top.tb_wb16_to_wb32.wb32_in.sel[2] top.tb_wb16_to_wb32.wb32_in.sel[1] top.tb_wb16_to_wb32.wb32_in.sel[0]
@200
-wb16
@28
top.tb_wb16_to_wb32.wb16_out.cyc
top.tb_wb16_to_wb32.wb16_out.stb
top.tb_wb16_to_wb32.wb16_out.we
@29
top.tb_wb16_to_wb32.wb16_in.stall
@22
#{top.tb_wb16_to_wb32.wb16_out.adr[31:0]} top.tb_wb16_to_wb32.wb16_out.adr[31] top.tb_wb16_to_wb32.wb16_out.adr[30] top.tb_wb16_to_wb32.wb16_out.adr[29] top.tb_wb16_to_wb32.wb16_out.adr[28] top.tb_wb16_to_wb32.wb16_out.adr[27] top.tb_wb16_to_wb32.wb16_out.adr[26] top.tb_wb16_to_wb32.wb16_out.adr[25] top.tb_wb16_to_wb32.wb16_out.adr[24] top.tb_wb16_to_wb32.wb16_out.adr[23] top.tb_wb16_to_wb32.wb16_out.adr[22] top.tb_wb16_to_wb32.wb16_out.adr[21] top.tb_wb16_to_wb32.wb16_out.adr[20] top.tb_wb16_to_wb32.wb16_out.adr[19] top.tb_wb16_to_wb32.wb16_out.adr[18] top.tb_wb16_to_wb32.wb16_out.adr[17] top.tb_wb16_to_wb32.wb16_out.adr[16] top.tb_wb16_to_wb32.wb16_out.adr[15] top.tb_wb16_to_wb32.wb16_out.adr[14] top.tb_wb16_to_wb32.wb16_out.adr[13] top.tb_wb16_to_wb32.wb16_out.adr[12] top.tb_wb16_to_wb32.wb16_out.adr[11] top.tb_wb16_to_wb32.wb16_out.adr[10] top.tb_wb16_to_wb32.wb16_out.adr[9] top.tb_wb16_to_wb32.wb16_out.adr[8] top.tb_wb16_to_wb32.wb16_out.adr[7] top.tb_wb16_to_wb32.wb16_out.adr[6] top.tb_wb16_to_wb32.wb16_out.adr[5] top.tb_wb16_to_wb32.wb16_out.adr[4] top.tb_wb16_to_wb32.wb16_out.adr[3] top.tb_wb16_to_wb32.wb16_out.adr[2] top.tb_wb16_to_wb32.wb16_out.adr[1] top.tb_wb16_to_wb32.wb16_out.adr[0]
#{top.tb_wb16_to_wb32.wb16_out.dat[31:0]} top.tb_wb16_to_wb32.wb16_out.dat[31] top.tb_wb16_to_wb32.wb16_out.dat[30] top.tb_wb16_to_wb32.wb16_out.dat[29] top.tb_wb16_to_wb32.wb16_out.dat[28] top.tb_wb16_to_wb32.wb16_out.dat[27] top.tb_wb16_to_wb32.wb16_out.dat[26] top.tb_wb16_to_wb32.wb16_out.dat[25] top.tb_wb16_to_wb32.wb16_out.dat[24] top.tb_wb16_to_wb32.wb16_out.dat[23] top.tb_wb16_to_wb32.wb16_out.dat[22] top.tb_wb16_to_wb32.wb16_out.dat[21] top.tb_wb16_to_wb32.wb16_out.dat[20] top.tb_wb16_to_wb32.wb16_out.dat[19] top.tb_wb16_to_wb32.wb16_out.dat[18] top.tb_wb16_to_wb32.wb16_out.dat[17] top.tb_wb16_to_wb32.wb16_out.dat[16] top.tb_wb16_to_wb32.wb16_out.dat[15] top.tb_wb16_to_wb32.wb16_out.dat[14] top.tb_wb16_to_wb32.wb16_out.dat[13] top.tb_wb16_to_wb32.wb16_out.dat[12] top.tb_wb16_to_wb32.wb16_out.dat[11] top.tb_wb16_to_wb32.wb16_out.dat[10] top.tb_wb16_to_wb32.wb16_out.dat[9] top.tb_wb16_to_wb32.wb16_out.dat[8] top.tb_wb16_to_wb32.wb16_out.dat[7] top.tb_wb16_to_wb32.wb16_out.dat[6] top.tb_wb16_to_wb32.wb16_out.dat[5] top.tb_wb16_to_wb32.wb16_out.dat[4] top.tb_wb16_to_wb32.wb16_out.dat[3] top.tb_wb16_to_wb32.wb16_out.dat[2] top.tb_wb16_to_wb32.wb16_out.dat[1] top.tb_wb16_to_wb32.wb16_out.dat[0]
#{top.tb_wb16_to_wb32.wb16_out.sel[3:0]} top.tb_wb16_to_wb32.wb16_out.sel[3] top.tb_wb16_to_wb32.wb16_out.sel[2] top.tb_wb16_to_wb32.wb16_out.sel[1] top.tb_wb16_to_wb32.wb16_out.sel[0]
@28
top.tb_wb16_to_wb32.wb16_in.ack
@22
#{top.tb_wb16_to_wb32.wb16_in.dat[31:0]} top.tb_wb16_to_wb32.wb16_in.dat[31] top.tb_wb16_to_wb32.wb16_in.dat[30] top.tb_wb16_to_wb32.wb16_in.dat[29] top.tb_wb16_to_wb32.wb16_in.dat[28] top.tb_wb16_to_wb32.wb16_in.dat[27] top.tb_wb16_to_wb32.wb16_in.dat[26] top.tb_wb16_to_wb32.wb16_in.dat[25] top.tb_wb16_to_wb32.wb16_in.dat[24] top.tb_wb16_to_wb32.wb16_in.dat[23] top.tb_wb16_to_wb32.wb16_in.dat[22] top.tb_wb16_to_wb32.wb16_in.dat[21] top.tb_wb16_to_wb32.wb16_in.dat[20] top.tb_wb16_to_wb32.wb16_in.dat[19] top.tb_wb16_to_wb32.wb16_in.dat[18] top.tb_wb16_to_wb32.wb16_in.dat[17] top.tb_wb16_to_wb32.wb16_in.dat[16] top.tb_wb16_to_wb32.wb16_in.dat[15] top.tb_wb16_to_wb32.wb16_in.dat[14] top.tb_wb16_to_wb32.wb16_in.dat[13] top.tb_wb16_to_wb32.wb16_in.dat[12] top.tb_wb16_to_wb32.wb16_in.dat[11] top.tb_wb16_to_wb32.wb16_in.dat[10] top.tb_wb16_to_wb32.wb16_in.dat[9] top.tb_wb16_to_wb32.wb16_in.dat[8] top.tb_wb16_to_wb32.wb16_in.dat[7] top.tb_wb16_to_wb32.wb16_in.dat[6] top.tb_wb16_to_wb32.wb16_in.dat[5] top.tb_wb16_to_wb32.wb16_in.dat[4] top.tb_wb16_to_wb32.wb16_in.dat[3] top.tb_wb16_to_wb32.wb16_in.dat[2] top.tb_wb16_to_wb32.wb16_in.dat[1] top.tb_wb16_to_wb32.wb16_in.dat[0]
[pattern_trace] 1
[pattern_trace] 0
testbench/wishbone/wb16_to_wb32/tb_wb16_to_wb32.vhd
0 → 100644
View file @
63f36713
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
work
.
wishbone_pkg
.
all
;
entity
tb_wb16_to_wb32
is
end
;
architecture
behav
of
tb_wb16_to_wb32
is
signal
clk
:
std_logic
;
signal
rst_n
:
std_logic
;
signal
wb16_in
:
t_wishbone_master_in
;
signal
wb16_out
:
t_wishbone_master_out
;
signal
wb32_in
:
t_wishbone_slave_in
;
signal
wb32_out
:
t_wishbone_slave_out
;
signal
reg1
:
std_logic_vector
(
31
downto
0
);
signal
reg0
:
std_logic_vector
(
31
downto
0
);
signal
done
:
boolean
:
=
false
;
begin
dut
:
entity
work
.
wb16_to_wb32
port
map
(
clk_i
=>
clk
,
rst_n_i
=>
rst_n
,
wb16_i
=>
wb16_out
,
wb16_o
=>
wb16_in
,
wb32_i
=>
wb32_out
,
wb32_o
=>
wb32_in
);
process
begin
clk
<=
'0'
;
wait
for
5
ns
;
clk
<=
'1'
;
wait
for
5
ns
;
if
done
then
wait
;
end
if
;
end
process
;
-- Simple slave with 2 registers.
process
(
clk
)
begin
if
rising_edge
(
clk
)
then
if
rst_n
=
'0'
then
reg1
<=
x"4400_3300"
;
reg0
<=
x"2200_1100"
;
wb32_out
.
ack
<=
'0'
;
else
if
wb32_in
.
cyc
=
'1'
and
wb32_in
.
stb
=
'1'
then
if
wb32_in
.
we
=
'1'
then
if
wb32_in
.
adr
(
2
)
=
'1'
then
reg1
<=
wb32_in
.
dat
;
else
reg0
<=
wb32_in
.
dat
;
end
if
;
else
if
wb32_in
.
adr
(
2
)
=
'1'
then
wb32_out
.
dat
<=
reg1
;
else
wb32_out
.
dat
<=
reg0
;
end
if
;
end
if
;
wb32_out
.
ack
<=
'1'
;
else
wb32_out
.
ack
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
process
;
process
procedure
wait_ack
is
begin
loop
wait
until
rising_edge
(
clk
);
exit
when
wb16_in
.
ack
=
'1'
;
end
loop
;
end
wait_ack
;
procedure
read16
(
addr
:
std_logic_vector
(
31
downto
0
))
is
begin
wb16_out
.
adr
<=
addr
;
wb16_out
.
we
<=
'0'
;
wb16_out
.
cyc
<=
'1'
;
wb16_out
.
stb
<=
'1'
;
wait_ack
;
end
read16
;
procedure
write16
(
addr
:
std_logic_vector
(
31
downto
0
);
dat
:
std_logic_vector
(
15
downto
0
))
is
begin
wb16_out
.
adr
<=
addr
;
wb16_out
.
dat
(
15
downto
0
)
<=
dat
;
wb16_out
.
we
<=
'1'
;
wb16_out
.
sel
<=
"0011"
;
wb16_out
.
cyc
<=
'1'
;
wb16_out
.
stb
<=
'1'
;
wait_ack
;
end
write16
;
begin
rst_n
<=
'0'
;
wait
until
rising_edge
(
clk
);
wait
until
rising_edge
(
clk
);
rst_n
<=
'1'
;
read16
(
x"0000_0000"
);
assert
wb16_in
.
dat
(
15
downto
0
)
=
x"1100"
severity
failure
;
read16
(
x"0000_0002"
);
assert
wb16_in
.
dat
(
15
downto
0
)
=
x"2200"
severity
failure
;
read16
(
x"0000_0004"
);
assert
wb16_in
.
dat
(
15
downto
0
)
=
x"3300"
severity
failure
;
read16
(
x"0000_0006"
);
assert
wb16_in
.
dat
(
15
downto
0
)
=
x"4400"
severity
failure
;
write16
(
x"0000_0002"
,
x"0220"
);
write16
(
x"0000_0000"
,
x"0110"
);
read16
(
x"0000_0000"
);
assert
wb16_in
.
dat
(
15
downto
0
)
=
x"0110"
severity
failure
;
read16
(
x"0000_0002"
);
assert
wb16_in
.
dat
(
15
downto
0
)
=
x"0220"
severity
failure
;
done
<=
true
;
report
"done"
;
wait
;
end
process
;
end
behav
;
\ No newline at end of file
tools/gen_buildinfo.py
View file @
63f36713
...
...
@@ -3,10 +3,16 @@
with
open
(
"buildinfo_pkg.vhd"
,
"w"
)
as
f
:
import
subprocess
import
time
commitid
=
subprocess
.
check_output
(
try
:
commitid
=
subprocess
.
check_output
(
[
"git"
,
"log"
,
"-1"
,
"--format=
%
H"
])
.
decode
()
.
strip
()
userid
=
subprocess
.
check_output
(
except
:
commitid
=
"unknown"
try
:
userid
=
subprocess
.
check_output
(
[
"git"
,
"config"
,
"--get"
,
"user.name"
])
.
decode
()
.
strip
()
except
:
userid
=
"unknown"
if
action
==
"simulation"
:
top
=
sim_top
tool
=
sim_tool
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment