Commit 6d382629 authored by Tristan Gingold's avatar Tristan Gingold

Add wb16_to_wb32 module.

parent 74355122
......@@ -201,6 +201,9 @@ 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
......
......@@ -26,6 +26,7 @@ modules = { "local" : [
"wb_ds182x_readout",
"wb_metadata",
"wb_split",
"wb16_to_wb32",
"wbgen2",
"wbgenplus",
]}
......
--------------------------------------------------------------------------------
-- 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;
[*]
[*] 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
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment