Created
November 28, 2011 18:49
-
-
Save fbrosser/1401498 to your computer and use it in GitHub Desktop.
Megagist
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -------------------------------------------------------------------------------- | |
| -- 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