Skip to content

Instantly share code, notes, and snippets.

@fbrosser
Created November 28, 2011 18:49
Show Gist options
  • Select an option

  • Save fbrosser/1401498 to your computer and use it in GitHub Desktop.

Select an option

Save fbrosser/1401498 to your computer and use it in GitHub Desktop.
Megagist
--------------------------------------------------------------------------------
-- Control Unit
-- Fredrik Brosser
-- EDA234, Group 2
--
-- FILE
-- ControlUnit.vhd
-- Last Updated: 2011-11-27
--
-- VERSION
-- Hardware ("production") v1.0
--
-- HARDWARE
-- Target Device: XC9572XL
-- I/O Pins Used:
-- Macrocells Used:
-- Product Terms Used:
--
-- DESCRIPTION
-- The Control Unit
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
Entity ControlUnit is
port( -- Global clock
clk : in std_logic;
-- Global reset
rstInt : in std_logic;
-- Push Buttons (Human Interface)
Buttons : in std_logic_vector(3 downto 0);
--FuncButton0 : in std_logic;
--FuncButton1 : in std_logic;
--TRdButton : in std_logic;
--TSelButton : in std_logic;
-- Read Temperature command signal to Temperature module
TRd : out std_logic;
-- Select signal for temperature sensors (sensor 0/1)
TSel : out std_logic;
-- Temperature Available signal from Temperature module
TAv : in std_logic;
-- Delay signal (from Temperature module)
delay : in std_logic;
-- Function control output to Function module
Func : out std_logic_vector(3 downto 0);
-- Enable signal for Function module
En : out std_logic;
-- Data input from DTMF module
DTMFData : in std_logic_vector(3 downto 0);
-- Data available signal from DTMF module
DAv : in std_logic;
-- Acknowledgement signal to DTMF module
Ack : out std_logic
-- Will be adding more signals later on. Something like :
-- R/W' out (DTMF module)
-- Play out (Sound module)
-- DoneS in (ound module)
);
end ControlUnit;
Architecture Behavioral of ControlUnit is
-- State variable (as integer)
signal state : integer range 0 to 3;
signal nextState : integer range 0 to 3;
signal TSelStatus : std_logic;
signal nextTSelStatus : std_logic;
begin
TSel <= TSelStatus;
En <= '1';
SyncP : process(clk, rstInt)
begin
if(not(rstInt) = '1') then
state <= 0;
TSelStatus <= '0';
Func <= (others => '0');
elsif(clk'Event and clk = '1') then
state <= nextState;
TSelStatus <= nextTSelStatus;
Func <= Buttons(3 downto 2) & "00";
end if;
end process;
TempP : process(Buttons, state, delay, TAv, TSelStatus)
begin
-- Defaults
nextState <= state;
nextTSelStatus <= TSelStatus;
Ack <= '0';
case state is
when 0 =>
-- OFF State
TRd <= '0';
if(Buttons(0) = '1' and delay = '1') then
nextState <= state + 1;
end if;
when 1 =>
TRd <= '1';
--nextTSelStatus <= Buttons(1);
if(DAv = '1') then
Ack <= '1';
if (DTMFData = "0001") then
nextTSelStatus <= '1';
else
nextTSelStatus <= '0';
end if;
end if;
--if(Buttons(1) = '1' and delay = '1') then
-- nextTSelStatus <= not(TSelStatus);
--end if;
if(delay = '1') then
nextState <= state + 1;
end if;
when 2 =>
TRd <= '0';
if(delay = '1') then
nextState <= state + 1;
end if;
when 3 =>
TRd <= '0';
if(TAv = '1' and delay = '1') then
nextState <= 0;
end if;
end case;
end process;
end Behavioral;
--------------------------------
--------------------------------------------------------------------------------
-- Function Module
-- Fredrik Brosser
-- EDA234, Group 2
--
-- FILE
-- FunctionModule.vhd
-- Last Updated: 2011-11-27
--
-- VERSION
-- Hardware ("production") v1.0
--
-- HARDWARE
-- Target Device: XC9572XL
-- I/O Pins Used:
-- Macrocells Used:
-- Product Terms Used:
--
-- DESCRIPTION
-- The Function Module is a simple module responsible for keeping track of and
-- updating the status (on/off) of the functions used.
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
Entity FunctionModule is
port( -- Global clock
clk : in std_logic;
-- Global reset
rstInt : in std_logic;
-- Enable signal from control unit
En : in std_logic;
-- Input from Control Unit
FuncIn : in std_logic_vector(3 downto 0);
-- Output to actual functions to be controlled
FuncOut : out std_logic_vector(3 downto 0)
);
end FunctionModule;
Architecture Behavioral of FunctionModule is
-- Internal vectors to keep track of function status
signal FuncStatus : std_logic_vector(3 downto 0);
signal nextFuncStatus : std_logic_vector(3 downto 0);
begin
-- Synchronous (clocked) process
SyncP : process(clk, rstInt)
begin
if(not(rstInt) = '1') then
-- Reset all functions (set to 0)
FuncStatus <= (others => '0');
elsif(clk'Event and clk = '1') then
FuncStatus <= nextFuncStatus;
end if;
end process;
FuncP : process(FuncIn, FuncStatus, En)
begin
nextFuncStatus <= FuncStatus;
FuncOut <= FuncStatus;
if(En = '1') then
-- Toggling of functions
for i in 0 to (FuncIn'length - 1) loop
if(FuncIn(i) = '1') then
nextFuncStatus(i) <= not(FuncStatus(i));
end if;
end loop;
end if;
end process;
end Behavioral;
-----------------------------
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15:36:10 11/23/2011
-- Design Name:
-- Module Name: dtmfDecoder - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dtmfdecoder is
port(
-- Clock
clk : in std_logic;
-- Asynchronous reset
rst : in std_logic;
-- Start signal
sigInit : in std_logic;
-- Early steering from DTMF chip
est : in std_logic;
-- Acknowledge signal from control unit
ack : in std_logic;
-- Input vector
extDataBus : inout std_logic_vector (3 downto 0);
-- Phi2 clock
phi2 : out std_logic;
-- Read/Write select
rw : out std_logic;
-- Register select
rs0 : out std_logic;
-- Data valid signal to control unit
dav : out std_logic;
-- Data bus to control unit
intDataBus : out std_logic_vector (3 downto 0);
-- LED DEBUG
led : out std_logic_vector (3 downto 0));
end dtmfdecoder;
architecture dtmfDecoder_bhv of dtmfDecoder is
-- State declaration
type stateType is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26);
-- Current state
signal state : stateType;
-- Next state
signal nextState : stateType;
-- Data to control unit
signal dataToControl : std_logic_vector(3 downto 0);
-- Next data to control unit
signal nextDataToControl : std_logic_vector(3 downto 0);
-- Output drive enable
signal outputEnable : std_logic;
-- Internal output data bus
signal outDataBus : std_logic_vector(3 downto 0);
-- Internal input data bus
begin
-- Synchronous process controling state changes
syncP : process(clk, rst)
begin
-- Asynchronous reset, active high
if (rst = '0') then
state <= s0;
dataToControl <= "0000";
-- Trigger state changes on positive clock flank
elsif (clk'Event and clk = '1') then
state <= nextState;
dataToControl <= nextDataToControl;
end if;
end process;
-- Asynchronous process describing states
stateP : process(state, sigInit, dataToControl, est, extDataBus, ack)
begin
-- Assign default values to signals
phi2 <= '0';
rw <= '0';
rs0 <= '0';
outputEnable <= '0';
outDataBus <= "0000";
--inDataBus <= "0000";
nextState <= state;
dav <= '0';
nextDataToControl <= dataToControl;
led <= "1111";
-- Send data to control unit
intDataBus <= dataToControl;
case state is
when s0 =>
if (sigInit = '0') then
nextState <= s1;
end if;
led <= "1110";
-- 1) Read Status Register
when s1 =>
rs0 <= '1';
rw <= '1';
nextState <= s2;
-- led <= "0001";
when s2 =>
rs0 <= '1';
rw <= '1';
phi2 <= '1';
nextState <= s3;
-- led <= "0010";
when s3 =>
rs0 <= '1';
rw <= '1';
nextState <= s4;
-- led <= "0011";
-- 2) Write "0000" to Control Register A
when s4 =>
rs0 <= '1';
outputEnable <= '1';
nextState <= s5;
-- led <= "0100";
when s5 =>
rs0 <= '1';
phi2 <= '1';
outputEnable <= '1';
nextState <= s6;
-- led <= "0101";
when s6 =>
rs0 <= '1';
outputEnable <= '1';
nextState <= s7;
-- led <= "0110";
-- 3) Write "0000" to Control Register A
when s7 =>
rs0 <= '1';
phi2 <= '1';
outputEnable <= '1';
nextState <= s8;
-- led <= "0111";
when s8 =>
rs0 <= '1';
outputEnable <= '1';
nextState <= s9;
-- led <= "1000";
-- 4) Write "1000" to Control Register A
when s9 =>
rs0 <= '1';
outDataBus <= "1000";
outputEnable <= '1';
nextState <= s10;
-- led <= "1001";
when s10 =>
rs0 <= '1';
phi2 <= '1';
outDataBus <= "1000";
outputEnable <= '1';
nextState <= s11;
-- led <= "1010";
when s11 =>
rs0 <= '1';
outDataBus <= "1000";
outputEnable <= '1';
nextState <= s12;
-- led <= "1011";
-- 5) Write "0000" to Control Register B
when s12 =>
rs0 <= '1';
outputEnable <= '1';
nextState <= s13;
-- led <= "1100";
when s13 =>
rs0 <= '1';
phi2 <= '1';
outputEnable <= '1';
nextState <= s14;
-- led <= "1101";
when s14 =>
rs0 <= '1';
outputEnable <= '1';
nextState <= s15;
-- led <= "1110";
-- 6) Read Status Register
when s15 =>
rs0 <= '1';
rw <= '1';
nextState <= s16;
-- led <= "1111";
when s16 =>
rs0 <= '1';
rw <= '1';
phi2 <= '1';
nextState <= s17;
when s17 =>
rs0 <= '1';
rw <= '1';
nextState <= s18;
-- Chip init ready, now init chip interface
-- Write "1101" to Control Register A
-- b0 set Enable tone output
-- b1 clr Enable DTMF
-- b2 set Enable IRQ
-- b3 clr Do not write to CRB in next write phase
when s18 =>
rs0 <= '1';
outDataBus <= "0101";
outputEnable <= '1';
nextState <= s19;
when s19 =>
rs0 <= '1';
phi2 <= '1';
outDataBus <= "0101";
outputEnable <= '1';
nextState <= s20;
when s20 =>
rs0 <= '1';
outDataBus <= "0101";
outputEnable <= '1';
nextState <= s21;
-- Idle state
when s21 =>
-- Wait for DTMF data present in the DTMF chip
if (est = '1') then
nextState <= s22;
end if;
led <= "0000";
-- Read DTMF data from MT8880C
when s22 =>
rw <= '1';
nextState <= s23;
when s23 =>
rw <= '1';
phi2 <= '1';
nextState <= s24;
when s24 =>
rw <= '1';
phi2 <= '1';
nextDataToControl <= extDataBus;
nextState <= s25;
when s25 =>
rw <= '1';
dav <= '1';
nextState <= s26;
-- Wait for control unit to acknowledge data
when s26 =>
dav <= '1';
--if (ack = '1') then
nextState <= s21;
--end if;
end case;
end process;
-- Asynchronous process controling tristate outputs
ouputEnableP : process(outputEnable, outDataBus)
begin
if (outputEnable = '1') then
extDataBus <= outDataBus;
else
extDataBus <= "ZZZZ";
end if;
end process;
end dtmfDecoder_bhv;
----------------------------
#PACE: Start of Constraints generated by PACE
#PACE: Start of PACE I/O Pin Assignments
NET "Buttons<0>" LOC = "P35" ;
NET "Buttons<1>" LOC = "P36" ;
NET "Buttons<2>" LOC = "P37" ;
NET "Buttons<3>" LOC = "P38" ;
NET "clk" LOC = "P5" ;
NET "delay" LOC = "P22" ;
NET "dtmfBus<0>" LOC = "P27" ;
NET "dtmfBus<1>" LOC = "P26" ;
NET "dtmfBus<2>" LOC = "P25" ;
NET "dtmfBus<3>" LOC = "P24" ;
NET "est" LOC = "P34" ;
NET "FuncOut<0>" LOC = "P40" ;
NET "FuncOut<1>" LOC = "P42" ;
NET "FuncOut<2>" LOC = "P43" ;
NET "FuncOut<3>" LOC = "P44" ;
NET "leds<0>" LOC = "P1" ;
NET "leds<1>" LOC = "P2" ;
NET "leds<2>" LOC = "P3" ;
NET "leds<3>" LOC = "P4" ;
NET "phi2" LOC = "P29" ;
NET "rs0" LOC = "P28" ;
NET "rst" LOC = "P39" ;
NET "rw" LOC = "P9" ;
NET "sinInit" LOC = "P6" ;
NET "TAv" LOC = "P18" ;
NET "TRd" LOC = "P19" ;
NET "TSel" LOC = "P20" ;
#PACE: Start of PACE Area Constraints
#PACE: Start of PACE Prohibit Constraints
#PACE: End of Constraints generated by PACE
---------------------------
----------------------------------------------------------------------------------
-- Temperature Module
-- DS18S20 1-Wire Communication
-- Fredrik Brosser
-- EDA234, Group 2
--
-- FILE
-- TempModule.vhd
-- Last Updated: 2011-11-22
--
-- VERSION
-- Hardware ("production") v1.2
--
-- HARDWARE
-- Target Device: XC9572XL
-- I/O Pins Used:
-- Macrocells Used:
-- Product Terms Used:
--
-- DESCRIPTION
-- Temperature module connected to two DS18S20 temperature sensors
-- communicating via a 1-wire serial protocol.
-- Module has to be reset, then the control unit can request a (by setting TRd high)
-- temperature read/conversion from the selected temperature sensor
-- (TSel = 0 or 1 for sensor 0 and 1, respectively). When there is
-- valid data on the bus (conversion and read cycle finished), the
-- temperature module responds by setting TAv (Temperature Available) high.
-- The temperature can the be read from the bus (Temp[7..0]).
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
Entity TemperatureModule is
port( -- Global clock
clk : in std_logic;
-- Global reset (Internal)
rstInt : in std_logic;
-- Temperature Read, trigger signal from Control Unit
TRd : in std_logic;
-- Signal to MUX, for selecting active sensor (0/1 for DQ0/DQ1, resp.)
TSel : in std_logic;
-- Temperature Available, indicates valid data on temperature output bus
TAv : out std_logic;
-- Internal temperature data output
Temp : out std_logic_vector(7 downto 0);
-- Export long delay
DelayOut : out std_logic;
-- Output to 1-Wire bus 1 (Temperature sensor 0)
DQ0 : inout std_logic;
-- Output to 1-Wire bus 0 (Temperature sensor 1)
DQ1 : inout std_logic
);
end TemperatureModule;
Architecture Behavioral of TemperatureModule is
-- Internal signal declarations
-- Buffer Enable
signal E : std_logic;
signal nextE : std_logic;
-- Valid data on temperature bus
signal TAvInt : std_logic;
signal nextTAvInt : std_logic;
-- State variable (as integer)
signal state : integer range 0 to 15;
signal nextState : integer range 0 to 15;
-- Data to be sent on bus
signal data : std_logic_vector(7 downto 0);
signal nextData : std_logic_vector(7 downto 0);
-- Internal temperature data output
signal tempOut : std_logic_vector(7 downto 0);
signal nextTempOut : std_logic_vector(7 downto 0);
-- Reading sign bit from sensor
signal signBit : std_logic;
signal nextSignBit : std_logic;
-- Sampling of bus by master
signal sample : std_logic;
signal nextSample : std_logic;
-- Counter used when sending a logical 0 on bus ('Zero Counter')
signal ZC : std_logic_vector(3 downto 0);
signal nextZC : std_logic_vector(3 downto 0);
-- Signal for keeping track of our progress through the read-cycle
signal progress : std_logic_vector(1 downto 0);
signal nextProgress : std_logic_vector(1 downto 0);
-- Counter for keeping track of which bit we are currently transmitting or sampling
signal bitCnt : std_logic_vector(2 downto 0);
signal nextBitCnt : std_logic_vector(2 downto 0);
-- Internal counter used to create timing pulses
signal cntInt : std_logic_vector(8 downto 0);
signal nextCntInt : std_logic_vector(8 downto 0);
-- Timing pulses, 512, 256, 8 and 4 us, respectively
signal delayLong : std_logic;
signal delayMedium : std_logic;
signal delayShort : std_logic;
signal delayTiny : std_logic;
-- Constants related to timing
constant LongDelayConstant : std_logic_vector := "111111110";
constant MediumDelayConstant : std_logic_vector := "11111111";
constant ShortDelayConstant : std_logic_vector := "111";
constant TinyDelayConstant : std_logic_vector := "11";
-- Base value (reset) for ZC
constant ZCrst : std_logic_vector := "1010";
-- Begin architecture
begin
-- Assign internal temperature available signal to output
TAv <= TAvInt;
-- Assign internal temperature bus to output
Temp <= tempOut;
-- Export long delay
DelayOut <= delayLong;
----------------------------------------------------------------------------------
-- SyncP, synchronous (clocked) process responsible for clocking in the new
-- states according to nextState
--
-- NB! : This is the only clocked process,
-- keeping track of all state or value updates (current => next)
--
----------------------------------------------------------------------------------
SyncP : process(clk, rstInt)
begin
if(not(rstInt) = '1') then
state <= 0;
cntInt <= (others => '0');
progress <= (others => '0');
bitCnt <= (others => '1');
data <= (others => '1');
tempOut <= (others => '1');
ZC <= ZCrst;
sample <= '1';
E <= '0';
signBit <= '0';
TAvInt <= '0';
elsif(clk'Event and clk = '1') then
state <= nextState;
ZC <= nextZC;
E <= nextE;
-- Increment internal counter
cntInt <= nextCntInt; -- cntInt + 1;
progress <= nextProgress;
bitCnt <= nextBitCnt;
data <= nextData;
sample <= nextSample;
tempOut <= nextTempOut;
signBit <= nextSignBit;
TAvInt <= nextTAvInt;
end if;
end process;
----------------------------------------------------------------------------------
-- BusP, process responsible for handling the buffered output to the bus,
-- according to the enable signal.
-- Works as a buffer and MUX for the 1-wire buses
--
----------------------------------------------------------------------------------
BusP : process(E, TSel)
begin
-- Default : both buses in threestate
DQ0 <= 'Z';
DQ1 <= 'Z';
-- Drive selected bus low if output enabled
if (E = '1') then
if(TSel = '0') then
DQ0 <= '0';
elsif(Tsel = '1') then
DQ1 <= '0';
end if;
end if;
end process;
----------------------------------------------------------------------------------
-- CountP, internal counter responsible for creating pulses with certain
-- time intervals. Uses a local (to the Architecture) counter variable.
--
----------------------------------------------------------------------------------
CountP : process(cntInt)
begin
-- Increment internal counter
nextCntInt <= cntInt + 1;
-- Gives pulses every 4 us
if(cntInt(1 downto 0) = TinyDelayConstant) then
delayTiny <= '1';
else
delayTiny <= '0';
end if;
-- Gives pulses every 8 us
if(cntInt(2 downto 0) = ShortDelayConstant) then
delayShort <= '1';
else
delayShort <= '0';
end if;
-- Gives pulses every 256 us
if(cntInt(7 downto 0) = MediumDelayConstant) then
delayMedium <= '1';
else
delayMedium <= '0';
end if;
-- Gives pulses every 512 us
if(cntInt = LongDelayConstant) then
delayLong <= '1';
nextCntInt <= (others => '0');
else
delayLong <= '0';
end if;
end process;
----------------------------------------------------------------------------------
-- ComP, State Machine handling the master side of the 1-wire bus
-- communication with the DS18S20. Divided into stages/modes as follows:
--
-- 1. INIT (Reset - Presence pulses)
-- 2. SEND (Transmission of data from Master to DS18S20)
-- 3. READ (Master reads data from DS18S20)
-- 4. IDLE (Bus is idle, pulled high by pull-up resistor)
--
----------------------------------------------------------------------------------
ComP : process(Trd, state, delayLong, delayMedium, delayShort, delayTiny, progress, ZC, bitCnt, Tsel, DQ0, DQ1, sample, data, E, tempOut, signBit, TAvInt)
begin
-- Defaults
nextState <= state;
nextProgress <= progress;
nextBitCnt <= bitCnt;
nextZC <= ZC;
nextSample <= sample;
nextData <= data;
nextE <= E;
nextTempOut <= tempOut;
nextSignBit <= signBit;
nextTAvInt <= TAvInt;
case state is
----------------------------------------------------------------------------------
-- INIT
----------------------------------------------------------------------------------
when 0 =>
-- Initialization of signals
nextProgress <= "00";
nextZC <= ZCrst;
nextSignBit <= '0';
nextE <= '0';
-- Wait for trigger from control unit
if(TRd = '1') then
nextState <= state + 1;
-- Entering the read cycle - data no longer valid
nextTAvInt <= '0';
end if;
when 1 =>
-- Enable output and send logical 0
nextE <= '0';
if(delayLong = '1') then
nextState <= state + 1;
end if;
when 2 =>
nextE <= '1';
if(delayLong = '1') then
nextState <= state + 1;
-- CCh, Skip ROM
nextData <= X"CC";
end if;
when 3 =>
-- Put bus into threestate and wait for response
nextE <= '0';
if(delayLong = '1') then
nextState <= state + 1;
end if;
----------------------------------------------------------------------------------
-- SEND
----------------------------------------------------------------------------------
-- Prepare for transmit of the byte in data
when 4 =>
-- Release bus and delay
nextE <= '0';
if(delayShort = '1') then
nextState <= 5;
end if;
-- Send logical 0 or 1 by driving bus low for a certain number of shortDelay periods (1 for 1's, ZCrst for 0's)
when 5 =>
-- Send logical 1
if(data(7-conv_integer(bitCnt)) = '1' and delayShort = '1') then
nextE <= '0';
-- Write slot complete, reset iterator and send next bit
if(ZC = "0000") then
nextState <= state + 1;
nextZC <= ZCrst;
-- Drive bus low for one delay period
elsif(ZC = ZCrst) then
nextE <= '1';
NextZC <= (ZC - 1);
-- Decrement iterator, bus is pulled high
else
NextZC <= (ZC - 1);
end if;
-- Send logical 0
elsif(data(7-conv_integer(bitCnt)) = '0' and delayShort = '1') then
nextE <= '1';
-- Write slot complete, reset iterator and send next bit
if(ZC = "0000") then
nextState <= state + 1;
nextZC <= ZCrst;
-- Decrement iterator, bus is kept low
else
NextZC <= (ZC - 1);
end if;
end if;
-- Recovery time between transmitted bits, and decrementing bit counter
when 6 =>
nextE <= '0';
if(delayShort = '1') then
if(bitCnt = "000") then
-- Done sending byte, move on and reset bit counter
nextState <= state + 1;
nextBitCnt <= (others => '1');
else
-- Send next bit
nextBitCnt <= bitCnt - 1;
nextState <= state - 1;
end if;
end if;
-- Done sending Command, disable buffer and prepare to send next byte,
-- or if the temp sensor is converting temperature, wait for it to finish
when 7 =>
nextE <= '0';
if(delayShort = '1') then
-- Converting temperature, go to read
if(progress = "01") then
nextState <= 9;
-- Move on
else
nextState <= state + 1;
end if;
end if;
-- Prepare to send next Command or start reading temperature
when 8 =>
nextE <= '0';
-- Increase progress variable. NB: assignment at end of process, will compare with 'old' value!
nextProgress <= progress + 1;
case progress is
when "00" =>
-- Issue Convert T Command (44h)
nextData <= X"44";
nextState <= 4;
when "01" =>
-- Do reset and Skip ROM (CCh)
nextData <= X"CC";
nextState <= 1;
when "10" =>
-- Issue Read Scratchpad Command (BEh)
nextData <= X"BE";
nextState <= 4;
when "11" =>
-- Master goes into Rx mode
nextState <= state + 1;
nextProgress <= "11";
when others =>
-- We should not be here, something is terribly wrong: do full reset and start over
nextProgress <= "00";
nextState <= 0;
end case;
----------------------------------------------------------------------------------
-- READ
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
--
-- Master reads 9 bytes from the bus, starting with LSB of Byte 0
-- However, we are only interested in the temperature registers (Byte 0 and 1),
-- so a reset pulse is given after nine bits (8 temp + 1 sign) have been read,
-- telling the DS18S20 to discontinue transfer.
--
----------------------------------------------------------------------------------
-- Delay and prepare for read phase
when 9 =>
nextE <= '0';
if(delayMedium = '1') then
nextState <= state + 1;
end if;
-- Pull bus low and wait for response (initiate read time slot, Tinit = 4 us)
when 10 =>
nextE <= '1';
if(delayTiny = '1') then
nextState <= state + 1;
end if;
-- Release bus and allow pullup resistor to perform its magic (Trc = 4 us)
when 11 =>
nextE <= '0';
if(delayTiny = '1') then
nextState <= state + 1;
end if;
-- Sample bus (Tsample = 4 us)
when 12 =>
nextE <= '0';
-- MUX'ed sampling from buses
if(Tsel = '0') then
nextSample <= DQ0;
elsif(Tsel = '1') then
nextSample <= DQ1;
end if;
if(delayTiny = '1') then
nextState <= state + 1;
end if;
-- Recovery time between read slots
when 13 =>
nextE <= '0';
if(delayMedium = '1') then
nextState <= state + 1;
end if;
-- Go back and sample next bit (or wait for conversion to finish)
when 14 =>
nextE <= '0';
-- Reading 9th bit (temperature sign) and finishing up reading
if(signBit = '1') then
nextTempOut(7) <= sample;
nextState <= state + 1;
nextProgress <= "00";
else
-- Waiting for conversion to finish
if(progress = "01") then
if(sample = '0') then
nextState <= 10;
elsif(sample = '1') then
nextState <= 8;
else
nextState <= 10;
end if;
elsif(progress = "11") then
nextState <= 10;
-- Reading temperature bit
if(bitCnt = "000") then
nextBitCnt <= (others => '1');
nextTempOut(conv_integer(bitCnt)) <= sample;
nextSignBit <= '1';
else
nextBitCnt <= bitCnt - 1;
nextTempOut(conv_integer(bitCnt)) <= sample;
end if;
-- Should not be here. If we are, go back and read again
else
nextState <= 10;
end if;
end if;
when 15 =>
-- Data on TOut bus is now valid. Go back and wait for next trigger.
nextTAvInt <= '1';
nextE <= '0';
nextState <= 0;
-- Other states. Should never be here.
when others =>
nextE <= '0';
nextState <= 0;
end case;
end process;
end Behavioral;
----------------------------
#PACE: Start of Constraints generated by PACE
#PACE: Start of PACE I/O Pin Assignments
NET "clk" LOC = "P5" ;
NET "DelayOut" LOC = "P22" ;
NET "DQ0" LOC = "P24" ;
NET "DQ1" LOC = "P25" ;
NET "rst" LOC = "P39" ;
NET "TAv" LOC = "P18" ;
NET "Temp<0>" LOC = "P35" ;
NET "Temp<1>" LOC = "P36" ;
NET "Temp<2>" LOC = "P37" ;
NET "Temp<3>" LOC = "P38" ;
NET "Temp<4>" LOC = "P40" ;
NET "Temp<5>" LOC = "P42" ;
NET "Temp<6>" LOC = "P43" ;
NET "Temp<7>" LOC = "P44" ;
NET "TRd" LOC = "P19" ;
NET "TSel" LOC = "P20" ;
#PACE: Start of PACE Area Constraints
#PACE: Start of PACE Prohibit Constraints
#PACE: End of Constraints generated by PACE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment