Commit 9027e98a authored by Tristan Gingold's avatar Tristan Gingold

Add wb_ds182x_readout

parent 3b4edf7e
......@@ -182,6 +182,8 @@ Directory [modules/wishbone](modules/wishbone) contains modules for wishbone.
- [wb_spi_flash](modules/wishbone/wb_spi_flash) is an spi flash controller
- [wb_uart](modules/wishbone/wb_uart) is an uart.
- [wb_vic](modules/wishbone/wb_vic) is the vectored interrupt controller.
- [wb_ds182x_readout](modules/wishbone/wb_ds182x_readout) is a direct
interface to the digital thermometer.
* There are utilities to handle a wishbone bus:
- [wb_clock_crossing](modules/wishbone/wb_clock_crossing) handle clock domain
......
......@@ -23,6 +23,7 @@ modules = { "local" : [
"wb_spi_flash",
"wb_simple_pwm",
"wb_i2c_bridge",
"wb_ds182x_readout",
"wbgen2",
"wbgenplus",
]}
......
files = ["wb_ds182x_regs.vhd",
"xwb_ds182x_readout.vhd"]
memory-map:
bus: wb-32-be
name: wb_ds182x_regs
description: Direct read of unique id and temperature
x-hdl:
busgroup: True
children:
- reg:
name: id
description: unique id
width: 64
access: ro
type: unsigned
- reg:
name: temperature
description: temperature
width: 32
access: ro
children:
- field:
name: data
description: temperature
range: 15-0
- reg:
name: status
description: status
width: 32
access: ro
children:
- field:
name: id_read
description: Set when unique id was read
range: 0
- field:
name: id_ok
description: Set when unique id was read, persist after reset
range: 1
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
entity wb_ds182x_regs is
port (
rst_n_i : in std_logic;
clk_i : in std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
-- unique id
id_i : in std_logic_vector(63 downto 0);
-- temperature
temperature_data_i : in std_logic_vector(15 downto 0);
-- Set when unique id was read
status_id_read_i : in std_logic;
-- Set when unique id was read, persist after reset
status_id_ok_i : in std_logic
);
end wb_ds182x_regs;
architecture syn of wb_ds182x_regs is
signal rd_int : std_logic;
signal wr_int : std_logic;
signal rd_ack_int : std_logic;
signal wr_ack_int : std_logic;
signal wb_en : std_logic;
signal ack_int : std_logic;
signal wb_rip : std_logic;
signal wb_wip : std_logic;
signal reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : std_logic;
begin
-- WB decode signals
wb_en <= wb_i.cyc and wb_i.stb;
process (clk_i, rst_n_i) begin
if rst_n_i = '0' then
wb_rip <= '0';
elsif rising_edge(clk_i) then
wb_rip <= (wb_rip or (wb_en and not wb_i.we)) and not rd_ack_int;
end if;
end process;
rd_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i, rst_n_i) begin
if rst_n_i = '0' then
wb_wip <= '0';
elsif rising_edge(clk_i) then
wb_wip <= (wb_wip or (wb_en and wb_i.we)) and not wr_ack_int;
end if;
end process;
wr_int <= (wb_en and wb_i.we) and not wb_wip;
ack_int <= rd_ack_int or wr_ack_int;
wb_o.ack <= ack_int;
wb_o.stall <= not ack_int and wb_en;
wb_o.rty <= '0';
wb_o.err <= '0';
-- Assign outputs
-- Process for write requests.
process (clk_i, rst_n_i) begin
if rst_n_i = '0' then
wr_ack_int <= '0';
elsif rising_edge(clk_i) then
wr_ack_int <= '0';
case wb_i.adr(3 downto 3) is
when "0" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- Register id
when "1" =>
-- Register id
when others =>
wr_ack_int <= wr_int;
end case;
when "1" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- Register temperature
when "1" =>
-- Register status
when others =>
wr_ack_int <= wr_int;
end case;
when others =>
wr_ack_int <= wr_int;
end case;
end if;
end process;
-- Process for registers read.
process (clk_i, rst_n_i) begin
if rst_n_i = '0' then
rd_ack1_int <= '0';
reg_rdat_int <= (others => 'X');
elsif rising_edge(clk_i) then
reg_rdat_int <= (others => '0');
case wb_i.adr(3 downto 3) is
when "0" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- id
reg_rdat_int <= id_i(63 downto 32);
rd_ack1_int <= rd_int;
when "1" =>
-- id
reg_rdat_int <= id_i(31 downto 0);
rd_ack1_int <= rd_int;
when others =>
rd_ack1_int <= rd_int;
end case;
when "1" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- temperature
reg_rdat_int(15 downto 0) <= temperature_data_i;
rd_ack1_int <= rd_int;
when "1" =>
-- status
reg_rdat_int(0) <= status_id_read_i;
reg_rdat_int(1) <= status_id_ok_i;
rd_ack1_int <= rd_int;
when others =>
rd_ack1_int <= rd_int;
end case;
when others =>
rd_ack1_int <= rd_int;
end case;
end if;
end process;
-- Process for read requests.
process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int) begin
-- By default ack read requests
wb_o.dat <= (others => '0');
case wb_i.adr(3 downto 3) is
when "0" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- id
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1" =>
-- id
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when others =>
rd_ack_int <= rd_int;
end case;
when "1" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- temperature
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1" =>
-- status
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when others =>
rd_ack_int <= rd_int;
end case;
when others =>
rd_ack_int <= rd_int;
end case;
end process;
end syn;
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- unit name: xwb_ds182x_readout
--
-- description: one wire temperature & unique id interface for
-- DS1822 and DS1820.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2013-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;
use IEEE.NUMERIC_STD.all;
use work.wishbone_pkg.all;
entity xwb_ds182x_readout is
generic (
g_CLOCK_FREQ_KHZ : integer := 40000; -- clk_i frequency in KHz
g_USE_INTERNAL_PPS : boolean := false);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
pps_p_i : in std_logic; -- pulse per second (for temperature read)
onewire_b : inout std_logic); -- Same as id_read_o, but not reset with rst_n_i
end xwb_ds182x_readout;
architecture arch of xwb_ds182x_readout is
signal id : std_logic_vector(63 downto 0); -- id_o value
signal temper : std_logic_vector(15 downto 0); -- temperature value (refreshed every second)
signal id_read : std_logic; -- id_o value is valid_o
signal id_ok : std_logic; -- Same as id_read_o, but not reset with rst_n_i
begin
i_readout: entity work.gc_ds182x_readout
generic map (
g_CLOCK_FREQ_KHZ => g_CLOCK_FREQ_KHZ,
g_USE_INTERNAL_PPS => g_USE_INTERNAL_PPS)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
pps_p_i => pps_p_i,
onewire_b => onewire_b,
id_o => id,
temper_o => temper,
id_read_o => id_read,
id_ok_o => id_ok);
i_regs: entity work.wb_ds182x_regs
port map (
rst_n_i => rst_n_i,
clk_i => clk_i,
wb_i => wb_i,
wb_o => wb_o,
id_i => id,
temperature_data_i => temper,
status_id_read_i => id_read,
status_id_ok_i => id_ok
);
end arch;
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