VHDL wrapper for 1-wire core for DS18B20 temperature sensor


#1

currently I am trying to write a VHDL wrapper for this Opencore Verilog module (1-wire master) so that I can send/receive from this temperature sensor (DS18B20). Here the datesheet of ds18b20
However I am struggling to understand the usage. Namely the read/write enable vs. the cyc bit in the control/status register of the 1-wire master module.

The code I have so far sets the cyc bit to 1 and the read/write enable to one simultaneously but does not cycle them during each bit. Is this correct or am I misunderstanding it? I’m new to VHDL/ reading a datasheet so I have been struggling over this for a few days. Any help would be appreciated.

I found this site that I have been using as a reference but it does not deal with the Verilog module that I am using.

I am also looking for tips on my code style, and VHDL tips in general.

My current code:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL; --may need to remove if signed not used

ENTITY one_wire_temp_probe_control IS
GENERIC (
one_us_divider_g : integer range 0 to 50 := 50 – clock divider for one micro second
);
PORT (
i_clk_50mhz : IN STD_LOGIC;
i_read_enable : IN std_logic;
io_temp_probe : INOUT STD_LOGIC; --how do i register an inout
o_temperature : OUT signed(6 DOWNTO 0);
o_temp_ready : OUT std_logic
);
END one_wire_temp_probe_control;

ARCHITECTURE rtl of one_wire_temp_probe_control IS
----temp commands----
CONSTANT skip_rom_c : std_logic_vector(7 DOWNTO 0) := x"CC"; --command to skip ROM identity of temperature sensor
CONSTANT convert_temp_c : std_logic_vector(7 DOWNTO 0) := x"44"; --command to start temperature conversion
CONSTANT read_scratchpad_c : std_logic_vector(7 DOWNTO 0) := x"BE"; --command to read the scratchpad i.e. get temperature data
CONSTANT command_bits_c : integer RANGE 0 TO 8 := 8; --number of bits in the above commands (note: range used to limit number of bits to minimum needed)
CONSTANT data_bits_c : integer RANGE 0 to 12 := 12; --number of bits in received data
----1-wire commands----
CONSTANT send_reset_pulse : std_logic_vector(7 DOWNTO 0) := “00001010”; --command to send reset pulse
CONSTANT write_command_structure_c : std_logic_vector(6 DOWNTO 0) := “0000000”; --structure of the command that must be passed to the 1-wire controller (----EDIT----)
----timing constants----
CONSTANT delay_65us_c : integer := one_us_divider_g * 65; --65 micro-second delay
CONSTANT delay_960us_c : integer := one_us_divider_g * 960; --960 micro-second delay
CONSTANT delay_750ms : integer := one_us_divider_g * 1000 * 750; --760 milli-second delay

----state machine----
TYPE state_type              IS (idle, presence_pulse, wait_presence_pulse, skip_rom, temp_conversion, wait_for_conversion,
                                 read_scratchpad, data_read, convert_data, wait_65us);
SIGNAL state                 : state_type := idle;
SIGNAL previous_state        : state_type := idle;
----1-wire----
SIGNAL read_enable_s, write_enable_s, reset_s, owr_e_s : std_logic := '0';
SIGNAL write_data_s, read_data_s                       : std_logic_vector(7 DOWNTO 0):= (OTHERS => '0'); --8 bit mode chosen in sockit_owm 
SIGNAL address_s                                       : std_logic_vector(1 DOWNTO 0) := "00"; 
SIGNAL timer_s                                         : integer := 0;
----commands---
SIGNAL bit_counter_command_s : integer RANGE 0 TO command_bits_c := 0;  --counter for bits in commands (note: not -1 due to using 9th bit as state change)
SIGNAL bit_counter_data_s    : integer RANGE 0 TO data_bits_c    := 0;  --counter for bits in data recieved
----temperature----
SIGNAL temperature_raw_data  : std_logic_vector(11 DOWNTO 0) := (OTHERS => '0');

----one wire control----
COMPONENT sockit_owm IS
PORT (
    ----control interface----
    clk     : IN std_logic;
    rst     : IN std_logic;
    bus_ren : IN std_logic;
    bus_wen : IN std_logic;
    bus_adr : IN std_logic_vector(7 DOWNTO 0);
    bus_wdt : IN std_logic_vector(7 DOWNTO 0);
    bus_rdt : OUT std_logic_vector(7 DOWNTO 0);
    bus_irq : OUT std_logic;
    ----1-wire interface----
    owr_p   : OUT std_logic; --verilog code is a one bit wide vector
    owr_e   : OUT std_logic;
    owr_i   : IN std_logic
);
END COMPONENT;

BEGIN

address_s <= "00"; --for the temp probe control we're not interested in other address spaces

PROCESS(i_clk_50mhz) BEGIN --state change
    IF rising_edge(i_clk_50mhz) THEN
        CASE state is
            WHEN idle =>
                o_temp_ready <= '0';
                IF (i_read_enable = '1') THEN
                    state <= presence_pulse;
                ELSE
                    state <= idle;
                END IF; 

            WHEN presence_pulse =>
            ----send reset/presence pulse----
                write_enable_s  <= '1';
                write_data_s    <= send_reset_pulse;
                timer_s         <= delay_960us_c;
                state           <= wait_presence_pulse;

            WHEN wait_presence_pulse =>
            ----wait for 960 micro seconds----
                read_enable_s <= '1';
                IF (timer_s = 0) THEN
                    IF (read_data_s(0) = '0') THEN
                        state <= skip_rom;
                    ELSIF (read_data_s(0) = '1') THEN
                        --precence not detected
                    ELSE
                        state <= wait_presence_pulse;
                    END IF;
                ELSE
                    timer_s <= timer_s - 1;
                    state   <= wait_presence_pulse;
                END IF;

            WHEN skip_rom =>
            ----send skip rom command----
                previous_state <= skip_rom;
                write_enable_s <= '1';
                    IF (bit_counter_command_s = command_bits_c) THEN
                        bit_counter_command_s <= 0;
                        state                 <= temp_conversion;
                    ELSE
                        write_data_s <= write_command_structure_c & skip_rom_c(bit_counter_command_s); ---command structure concatonated with 1 bit from command
                        bit_counter_command_s <= bit_counter_command_s + 1;
                        timer_s               <= delay_65us_c;
                        state                 <= wait_65us;
                    END IF;   

            WHEN temp_conversion =>
            ----send temp conversion command to probe----
                previous_state <= temp_conversion;
                IF (bit_counter_command_s = bit_counter_command_s) THEN
                    bit_counter_command_s   <= 0;
                    timer_s                 <= delay_750ms;
                    state                   <= wait_for_conversion;
                ELSE
                    write_data_s <= write_command_structure_c & convert_temp_c(bit_counter_command_s); ---command structure concatonated with 1 bit from command
                    bit_counter_command_s   <= bit_counter_command_s + 1;
                    timer_s                 <= delay_65us_c;
                    state                   <= wait_65us;
                END IF;

            WHEN wait_for_conversion =>
            ----wait for temperature conversion to finish----
                IF (timer_s = 0) then
                    state <= read_scratchpad;
                ELSE
                    timer_s <= timer_s - 1;
                END IF;

            WHEN read_scratchpad =>
            ----send read scratchpad command----
                previous_state <= read_scratchpad;
                IF (bit_counter_command_s = command_bits_c) THEN
                    state                 <= data_read;
                    bit_counter_command_s <= 0;
                ELSE
                    write_data_s <= write_command_structure_c & read_scratchpad_c(bit_counter_command_s); ---command structure concatonated with 1 bit from command
                    bit_counter_command_s <= bit_counter_command_s + 1;
                    timer_s               <= delay_65us_c;
                    state                 <= wait_65us;
                END IF;

            WHEN data_read =>
            ----read incoming data----
                previous_state <= data_read;
                read_enable_s <= '1';
                IF (bit_counter_data_s = data_bits_c) THEN
                    bit_counter_data_s <= 0; --may need to invert this
                    state              <= convert_data;
                ELSE
                    temperature_raw_data(bit_counter_data_s) <= read_data_s(0);
                    bit_counter_data_s                       <= bit_counter_data_s + 1;
                    timer_s                                  <= delay_65us_c;
                    state                                    <= wait_65us;
                END IF;

            WHEN convert_data =>
            ----convert raw data into temperature----
                o_temp_ready <= '1';

            WHEN wait_65us =>
            ----wait for read/write cycle to finish----
                IF (timer_s = 0) THEN
                    state <= previous_state;
                ELSE 
                    timer_s <= timer_s - 1;   
                    state   <= wait_65us;
                END IF;
        END CASE;
    END IF;
END PROCESS;

----one wire component instantiation----
one_wire_control : sockit_owm
PORT MAP(
    ----control interface----
    clk     => i_clk_50mhz,
    rst     => reset_s,
    bus_ren => read_enable_s,
    bus_wen => write_enable_s,
    bus_adr => address_s,
    bus_wdt => write_data_s,
    bus_rdt => read_data_s,
    bus_irq => OPEN,
    ----1-wire interface----
    owr_p   => OPEN,
    owr_e   => owr_e_s,
    owr_i   => io_temp_probe
);
io_temp_probe <= owr_e_s ? '0' : 'Z'; --I also need help converting this line to VHDL

END rtl;

Thank you in advance.