Jump to content
  • 0

i want testbench simulation for this code


Hos Sam97

Question

------------------------------------------------- --------------------------
-- DS18B20.vhd - DS18B20 temperature sensor communication module
-------------------------------------------------- --------------------------
-- Author: Pavel Gregar
-- Created: 15:11:15 11/29/2013
-- Module: DS18B20 - Behavioral
-- Project: Weather station
-- Target device: Nexys4
-- Use tools: Xilinx 14.6
---------------------------------------------------------------------------

---------------------------------------------------------------------------
-- This module is used to communicate with the DS18B20 temperature sensor. Use the command sequence
-- 44h (CONVERT TEMPERATURE),
-- CCH (SKIP ROM),
-- BEh (READ SCRATCHPAD) is loaded The contents of the scrathpad sensor memory that is sent to the CRC port for dataOut.
-- Module ports:
-- clk1m           1 MHz clock.
-- crc_en          Control of starting CRC calculations from data received from the sensor sent to the dataOut port.
-- ds_data_bus     1-wire I / O, sensor input / output data port.
-- dataOut         Output a data signal containing the contents of the scratchpad memory
----------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity DS18B20 is
port
(
  clk1m                : IN        STD_LOGIC;
  crc_en                : OUT        STD_LOGIC;
  dataOut            : OUT        STD_LOGIC_VECTOR(71 downto 0);
  ds_data_bus      : INOUT    STD_LOGIC
);
end DS18B20;

architecture Behavioral of DS18B20 is
 
 --FSM states needed
TYPE STATE_TYPE is (WAIT_800ms, RESET, PRESENCE, SEND, WRITE_BYTE, WRITE_LOW, WRITE_HIGH, GET_DATA, READ_BIT);


SIGNAL state: STATE_TYPE;                                -- present state of FSM
SIGNAL data    : STD_LOGIC_VECTOR(71 downto 0);             -- read data from scratchpad sensor memory
SIGNAL S_reset    : STD_LOGIC;                              -- synchronous reset
SIGNAL i:INTEGER RANGE 0 TO 799999;                      -- citac
SIGNAL write_command : STD_LOGIC_VECTOR(7 downto 0);     -- sensor instruction sent
SIGNAL presence_signal        : STD_LOGIC;                  -- signal for sensor detection on the bus
SIGNAL WRITE_BYTE_CNT    : INTEGER RANGE 0 TO 8    := 0;        -- for sending bytes
SIGNAL write_low_flag    : INTEGER RANGE 0 TO 2    := 0;        -- position flag in WRITE_LOW state
SIGNAL write_high_flag    : INTEGER RANGE 0 TO 2    := 0;        --    position flag in WRITE_HIGH state
SIGNAL read_bit_flag        : INTEGER RANGE 0 TO 3    := 0;        -- position flag in READ_BIT state
SIGNAL GET_DATA_CNT        : INTEGER RANGE 0 TO 72    := 0;        -- citation for the number of read bits

begin

    -- Process for communication with DS18B20 sensor
    process(clk1m)
    --- output data in case of sensor detection error on bus
    CONSTANT PRESENCE_ERROR_DATA    : STD_LOGIC_VECTOR(71 downto 0):= "101010101010101010101010101010101010101010101010101010101010101010101010";
    VARIABLE bit_cnt    : INTEGER RANGE 0 TO 71;    --- just read bit
    VARIABLE flag        : INTEGER RANGE 0 TO 5;        --flag for sent command

    begin
        if rising_edge(clk1m) then
            case    state is
                when RESET =>                                                                -- sensor reset status
                    S_reset <= '0';                                                        -- reset instruction
                    if (i = 0) then
                        ds_data_bus <= '0';                                                --    start of reset pulse
                    elsif (i = 485) then
                        ds_data_bus <= 'Z';                                                -- bus release
                    elsif (i = 550) then
                        presence_signal <= ds_data_bus;                                -- taking a sample to detect the presence of the sensor
                    elsif (i = 1000) then
                        state <= PRESENCE;                                                -- transition to PRESENCE    
                    end if;
            
                when PRESENCE =>                                                            -- state for detecting the presence of a sensor on the busi
                    -- Bus sensor detection
                    if (presence_signal = '0' and ds_data_bus = '1') then        -- the sensor has been detected
                        S_reset <= '1';                                                    -- reset instruction
                        state      <= SEND;                                                    -- initialization complete, transition to SEND state
                    else                                                                        
                    -- sensor not detected
                        S_reset    <= '1';                                                    --  reset instruction
                        dataOut     <= PRESENCE_ERROR_DATA;                                -- setting data indicating error to output
                        crc_en    <= '1';                                                    -- start of CRC calculation
                        state        <= WAIT_800ms;                                            -- transition to WAIT_800ms
                    end if;

                when SEND =>                                                                -- status for sending command for sensor
                    -- sequence of commands sent by flag flag
                    
                    if (flag = 0) then                                                    -- first command
                        flag := 1;
                        write_command <="11001100";                                     -- command CCh - SKIP ROM
                        state           <= WRITE_BYTE;                                    -- transition to WRITE BYTE
                    
                    elsif (flag = 1) then                                                -- second order
                        flag := 2;
                        write_command <="01000100";                                     -- order 44h - CONVERT TEMPERATURE
                        state           <= WRITE_BYTE;                                    -- transition to WRITE BYTE
                    
                    elsif (flag = 2) then                                                -- the third command
                        flag := 3;    
                        state <= WAIT_800ms;                                             -- transition to WAIT_800ms, waiting for command to end 44h
                    
                    elsif (flag = 3) then                                                -- the fourth command
                        flag := 4;
                        write_command <="11001100";                                     -- command CCh - SKIP ROM
                        state              <= WRITE_BYTE;                                    -- transition to WRITE BYTE
                    
                    elsif (flag = 4) then                                                -- fourth command
                        flag := 5;
                        write_command <="10111110";                                     -- command BEh - READ SCRATCHPAD
                        state              <= WRITE_BYTE;                                    -- transition to WRITE BYTE
                    
                    elsif (flag = 5) then                                                -- stop sending command
                        flag := 0;                                                            -- reset flag for outgoing command
                        state <= GET_DATA;                                                -- transition to GET_DATA
                    end if;

                when  WAIT_800ms =>                                                        -- waiting state for 800 ms
                    CRC_en <= '0';                                                            -- reset flag to start CRC calculation
                    S_reset <= '0';                                                        -- running instruction
                 if (i = 799999) then                                                    -- end of quote period
                        S_reset <='1';                                                        -- reset instruction
                        state      <= RESET;                                                    -- return to the RESET state
                    end if;

                when GET_DATA =>                                                            -- scratchpad memory read status
                    case GET_DATA_CNT is                                                    -- position in GET_DATA state
                        when 0 to 71=>                                                        -- read individual bits of scratchpad memory
                            ds_data_bus  <= '0';                                            -- start reading on the bus
                            GET_DATA_CNT <= GET_DATA_CNT + 1;                        -- increment quotes for just read bit
                            state          <= READ_BIT;                                    -- transition to READ_BIT
                        when 72=>                                                            -- read memory (72 bits)
                            bit_cnt := 0;                                                    -- reset quote for just read bit
                            GET_DATA_CNT <=0;                                                -- reset instruction of read bits
                            dataOut      <= data(71 downto 0);                            -- send the read data to the output port
                            CRC_en          <= '1';                                            -- start calculating CRC of read data
                            state          <= WAIT_800ms;                                -- return to WAIT_800ms
                        when others =>                                                         -- error in GET_DATA state
                            read_bit_flag <= 0;                                            -- reset position in READ_BIT state
                            GET_DATA_CNT  <= 0;                                             -- reset citation for the number of read bits
                    end case;

                when READ_BIT =>                                                            -- state for reading the bit
                    -- bit read sequence controlled by the read_bit_flag
                    case read_bit_flag is                                                --position in READ_BIT
                        when 0=>                                                                -- sending start time slot for reading
                            read_bit_flag <= 1;
                        when 1=>                                                                
                            ds_data_bus <= 'Z';                                            -- releasing the bus to receive a bit from the sensor
                            S_reset         <= '0';                                            -- turn on instruction
                            if (i = 13) then                                                --waiting 14 us
                                S_reset         <= '1';                                        -- reset instruction
                                read_bit_flag <= 2;
                            end if;
                        when 2=>                                                                -- sampling of data from the bus
                            data(bit_cnt)    <= ds_data_bus;                            -- saving a sample of data into the registr
                            bit_cnt := bit_cnt + 1;                                        -- increase citation for just read bit
                            read_bit_flag    <= 3;
                        when 3=>                                                                -- complete the time slot
                            S_reset <= '0';                                                -- turn on quotes
                            if (i = 63) then                                                -- waiting 62 us
                                S_reset<='1';                                                -- reset quote
                                read_bit_flag <= 0;                                        -- reset position in READ_BIT state
                                state           <= GET_DATA;                                -- return to GET_DATA
                            end if;
                        when others =>                                                     -- error in READ_BIT state
                            read_bit_flag <= 0;                                            -- reset position in READ_BIT state
                            bit_cnt          := 0;                                            -- reset quote for just read bit
                            GET_DATA_CNT  <= 0;                                            -- reset citation of read bits
                            state              <= RESET;                                        -- Sensor reset
                    end case;

                when WRITE_BYTE =>                                                        -- state for writing a data byte on the bus
                    -- byte sequence of data byte controlled by WRITE_BYTE CNT
                    case WRITE_BYTE_CNT is                                                -- position in WRITE_BYTE
                        when 0 to 7=>                                                        -- sending bit 0-7
                            if (write_command(WRITE_BYTE_CNT) = '0') then        -- the bit sent is log. 0
                                state <= WRITE_LOW;                                         -- transition to WRITE_LOW
                            else                                                                -- the bit sent is log. 1
                                state <= WRITE_HIGH;                                        -- prechod do stavu WRITE_HIGH
                            end if;
                            WRITE_BYTE_CNT <= WRITE_BYTE_CNT + 1;                    -- inkrementace citace odesilaneho bitu
                        when 8=>                                                                -- odesilani bajtu dokonceno
                            WRITE_BYTE_CNT <= 0;                                            -- reset citace odesilaneho bitu
                            state                <= SEND;                                        -- navrat do stavu SEND
                        when others=>                                                        -- chyba ve stavu WRITE_BYTE
                            WRITE_BYTE_CNT  <= 0;                                        -- reset citace odesilaneho bitu
                            write_low_flag  <= 0;                                        -- reset pozice ve stavu WRITE_LOW
                            write_high_flag <= 0;                                        -- reset pozice ve stavu WRITE_HIGH
                            state            <= RESET;                                    -- reset senzoru
                        end case;

                when WRITE_LOW =>                                                            -- stav pro zapis log. 0 na sbernici
                    -- casovy slot pro zapis log 0 rizeny priznakem write_low_flag
                    case write_low_flag is                                                -- pozice ve stavu WRITE_LOW
                        when 0=>                                                                -- vyslani zacatku casoveho slotu pro zapis log. 0
                            ds_data_bus <= '0';                                            -- zacatek casoveho slotu
                            S_reset         <= '0';                                            -- zapnuti citace
                            if (i = 59) then                                                -- cekani 60 us
                                S_reset           <='1';                                        -- reset citace
                                write_low_flag <= 1;
                            end if;
                        when 1=>                                                                -- uvolneni sbernice pro ukonceni casoveho slotu
                            ds_data_bus <= 'Z';                                            -- uvolneni sbernice
                            S_reset         <= '0';                                            -- zapnuti citace
                            if (i = 3) then                                                -- cekani 4 us na ustaleni sbernice
                                S_reset            <= '1';                                    -- reset citace
                                write_low_flag <= 2;
                            end if;
                        when 2=>                                                                -- konec zapisu log. 0
                            write_low_flag <= 0;                                            -- reset pozice ve stavu WRITE_LOW
                            state            <= WRITE_BYTE;                                -- navrat do stavu WRITE_BYTE
                        when others=>                                                        -- chyba zapisu log. 0
                            WRITE_BYTE_CNT  <= 0;                                        -- reset citace odesilaneho bitu
                            write_low_flag  <= 0;                                        -- reset pozice ve stavu WRITE_LOW
                            state             <= RESET;                                    -- reset senzoru
                    end case;

                when WRITE_HIGH =>                                                        -- stav pro zapis log. 1 na sbernici
                    -- casovy slot pro zapis log 1 rizeny priznakem write_high_flag
                    case write_high_flag is                                                -- pozice ve stavu WRITE_HIGH
                        when 0=>                                                                -- vyslani zacatku casoveho slotu pro zapis log. 1
                            ds_data_bus <= '0';                                            -- zacatek casoveho slotu
                            S_reset <= '0';                                                -- zapnuti citace
                            if (i = 9) then                                                -- cekani 10 us
                                S_reset             <= '1';                                    -- reset citace
                                write_high_flag <= 1;
                            end if;
                        when 1=>                                                                -- uvolneni sbernice pro ukonceni casoveho slotu
                            ds_data_bus <= 'Z';                                            -- uvolneni sbernice
                            S_reset         <= '0';                                            -- zapnuti citace
                            if (i = 53) then                                                -- cekani 54 us
                                S_reset            <= '1';                                    -- reset citace
                                write_high_flag <= 2;
                            end if;
                        when 2=>                                                                -- konec zapisu log. 1
                            write_high_flag <= 0;                                        -- reset pozice ve stavu WRITE_HIGH
                            state              <= WRITE_BYTE;                            -- navrat do stavu WRITE BYTE
                        when others =>                                                        -- chyba zapisu log. 1
                            WRITE_BYTE_CNT  <= 0;                                        -- reset citace odesilaneho bitu
                            write_high_flag <= 0;                                        -- reset pozice ve stavu WRITE_HIGH
                            state             <= RESET;                                    -- reset senzoru
                    end case;

                when others =>                                                                -- chyba FSM
                    state <= RESET;                                                        -- reset senzoru
                    
            end case;
        end if;
    end process;

    -- Proces citace se synchronnim resetem
    process(clk1m, S_reset)

    begin
        if (rising_edge(clk1m)) then
            if (S_reset = '1')then        -- reset citace
                i <= 0;                        -- vynulovani citace
            else
                i <= i + 1;                    -- inkrementace citace
            end if;
        end if;
    end process;

end Behavioral;

Link to comment
Share on other sites

1 answer to this question

Recommended Posts

 

So write one.

If you don't know how to write a testbench you can look through the code in this project: https://forum.digilentinc.com/topic/20479-inter-board-data-transfer-project/

It helps if you have some idea of how the code you want to test works.

[edit] Warning! Writing good testbench code is harder than writing the code that you want to test. But everyone has to start somewhere.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...