-------------------------------------------------------------------------------- -- SpecialScreenPrinter.vhd -- prints dynamic text based on the current state and the contents of RAM or -- variable registers. -- -- 156 (13%) logic cells, complex, 8.1 -- 171 (14%) logic cells, 77.5ns, 12.90MHz, simple, 7.21 -- 172 (14%) logic cells, 65.2ns, 15.33MHz, simple, 8.1 -- 160 (13%) logic cells, 82.5ns, 12.12MHz (simple, 7.21) -- 169 (14%) logic cells, (simple, 7.21, new handshaking) -- -------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library work; use work.Constants_Package.all; use work.Time_Package.all; use work.Control_Package.all; use work.BCD_Package.all; entity SpecialScreenPrinter is port( clock: in std_logic; start: in std_logic; ready: in std_logic; done: out std_logic; --busy: out std_logic; digit: out std_logic_vector(BCD_WIDTH-1 downto 0); LCDinstruction: out std_logic_vector(LCD_INSTRUCTION_WIDTH-1 downto 0); currentState: in std_logic_vector(STATE_WIDTH-1 downto 0); currentYear: in std_logic_vector(YEAR_WIDTH-1 downto 0); currentMonth: in std_logic_vector(MONTH_WIDTH-1 downto 0); currentDay: in std_logic_vector(DAY_WIDTH-1 downto 0); currentHour: in std_logic_vector(HOUR_WIDTH-1 downto 0); currentMinute: in std_logic_vector(MINUTE_WIDTH-1 downto 0); currentSecond: in std_logic_vector(SECOND_WIDTH-1 downto 0); currentWeekday: in std_logic_vector(WEEKDAY_WIDTH-1 downto 0); eventHour: std_logic_vector(HOUR_WIDTH-1 downto 0); eventMinute: std_logic_vector(MINUTE_WIDTH-1 downto 0); eventWeekday: std_logic_vector(WEEKDAY_WIDTH-1 downto 0) ); end SpecialScreenPrinter; architecture printer of SpecialScreenPrinter is constant NORMAL_SCREEN_WIDTH: positive := 4; constant EDIT_SCREEN_WIDTH: positive := 4; -- n = normal state -- w = edit weekly event state -- yr: year, mo: month, da: day, hr: hour, mi: minute, se: second, wk: weekday -- b# = blank position -- c = colon constant nyr3: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "0000"; constant nyr2: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "0001"; constant nyr1: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "0010"; constant nyr0: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "0011"; constant nmo1: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "0100"; constant nmo0: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "0101"; constant nda1: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "0110"; constant nda0: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "0111"; constant nhr1: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "1000"; constant nhr0: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "1001"; constant nmi1: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "1010"; constant nmi0: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "1011"; constant nse1: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "1100"; constant nse0: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "1101"; constant nwk0: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "1110"; constant nb2f: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0) := "1111"; constant whr1: std_logic_vector(EDIT_SCREEN_WIDTH-1 downto 0) := "0000"; constant whr0: std_logic_vector(EDIT_SCREEN_WIDTH-1 downto 0) := "0001"; constant wmi1: std_logic_vector(EDIT_SCREEN_WIDTH-1 downto 0) := "0010"; constant wmi0: std_logic_vector(EDIT_SCREEN_WIDTH-1 downto 0) := "0011"; constant wwk0: std_logic_vector(EDIT_SCREEN_WIDTH-1 downto 0) := "0100"; constant wb25: std_logic_vector(EDIT_SCREEN_WIDTH-1 downto 0) := "0101"; signal StatusPrintNormalState: std_logic_vector(NORMAL_SCREEN_WIDTH-1 downto 0); signal StatusPrintEditWeeklyState: std_logic_vector(EDIT_SCREEN_WIDTH-1 downto 0); signal active: std_logic; signal backing_up: std_logic; signal instruction_sent: std_logic; begin --busy <= active; specialPrinter: process(clock) is begin if rising_edge(clock) then if start = '1' then active <= '1'; done <= '0'; backing_up <= '0'; StatusPrintNormalState <= nyr3; StatusPrintEditWeeklyState <= whr1; --LCDinstruction <= GOTO_LINE2; LCDinstruction <= NO_ACTION; instruction_sent <= '0'; elsif active = '1' and ready = '1' then if instruction_sent = '0' then instruction_sent <= '1'; case currentState is ------------------------------------------------------------------------ when NORMAL_STATE | ALARM_STATE => case StatusPrintNormalState is when nyr3 => digit <= currentYear(4*BCD_WIDTH-1 downto 3*BCD_WIDTH); when nyr2 => digit <= currentYear(3*BCD_WIDTH-1 downto 2*BCD_WIDTH); when nyr1 => digit <= currentYear(2*BCD_WIDTH-1 downto 1*BCD_WIDTH); when nyr0 => digit <= currentYear(1*BCD_WIDTH-1 downto 0*BCD_WIDTH); when nmo1 => digit <= currentMonth(2*BCD_WIDTH-1 downto 1*BCD_WIDTH); when nmo0 => digit <= currentMonth(1*BCD_WIDTH-1 downto 0*BCD_WIDTH); when nda1 => digit <= currentDay(2*BCD_WIDTH-1 downto 1*BCD_WIDTH); when nda0 => digit <= currentDay(1*BCD_WIDTH-1 downto 0*BCD_WIDTH); when nhr1 => digit <= currentHour(2*BCD_WIDTH-1 downto 1*BCD_WIDTH); when nhr0 => digit <= currentHour(1*BCD_WIDTH-1 downto 0*BCD_WIDTH); when nmi1 => digit <= currentMinute(2*BCD_WIDTH-1 downto 1*BCD_WIDTH); when nmi0 => digit <= currentMinute(1*BCD_WIDTH-1 downto 0*BCD_WIDTH); when nse1 => digit <= currentSecond(2*BCD_WIDTH-1 downto 1*BCD_WIDTH); when nse0 => digit <= currentSecond(1*BCD_WIDTH-1 downto 0*BCD_WIDTH); when nwk0 => digit <= currentWeekday(1*BCD_WIDTH-1 downto 0*BCD_WIDTH); when others => -- do nothing end case; case StatusPrintNormalState is when nyr3 | nyr2 | nyr1 | nyr0 | nmo1 | nmo0 | nda1 | nda0 | nhr1 | nhr0 | nmi1 | nmi0 | nse1 | nse0 | nwk0 => -- if backing_up = '0' then LCDinstruction <= PRINT_CHAR; StatusPrintNormalState <= StatusPrintNormalState + '1'; -- else -- if StatusPrintNormalState = nyr3 and backing_up = '1' then -- -- last state; deactivate myself -- active <= '0'; -- done <= '1'; -- backing_up <= '0'; -- LCDinstruction <= NO_ACTION; -- else -- LCDinstruction <= BACKUP_CURSOR; -- StatusPrintNormalState <= StatusPrintNormalState - '1'; -- end if; -- end if; when nb2f => -- last state; deactivate myself active <= '0'; done <= '1'; backing_up <= '0'; LCDinstruction <= NO_ACTION; -- backing_up <= '1'; -- LCDinstruction <= BACKUP_CURSOR; -- StatusPrintNormalState <= StatusPrintNormalState - '1'; when others => LCDinstruction <= NO_ACTION; end case; ------------------------------------------------------------------------ when EDIT_WEEKLY_EVENT_STATE => if backing_up = '0' then case StatusPrintEditWeeklyState is when whr1 => digit <= eventHour(2*BCD_WIDTH-1 downto 1*BCD_WIDTH); when whr0 => digit <= eventHour(1*BCD_WIDTH-1 downto 0*BCD_WIDTH); when wmi1 => digit <= eventMinute(2*BCD_WIDTH-1 downto 1*BCD_WIDTH); when wmi0 => digit <= eventMinute(1*BCD_WIDTH-1 downto 0*BCD_WIDTH); when wwk0 => digit <= eventWeekday(1*BCD_WIDTH-1 downto 0*BCD_WIDTH); when others => -- do nothing end case; case StatusPrintEditWeeklyState is when whr1 | whr0 | wmi1 | wmi0 | wwk0 => LCDinstruction <= PRINT_CHAR; StatusPrintEditWeeklyState <= StatusPrintEditWeeklyState + '1'; when wb25 => backing_up <= '1'; LCDinstruction <= BACKUP_CURSOR; StatusPrintEditWeeklyState <= StatusPrintEditWeeklyState - '1'; when others => LCDinstruction <= NO_ACTION; end case; else -- backing_up = '1' if StatusPrintEditWeeklyState = whr1 and backing_up = '1' then -- last state; deactivate myself active <= '0'; done <= '1'; backing_up <= '0'; LCDinstruction <= NO_ACTION; else LCDinstruction <= BACKUP_CURSOR; StatusPrintEditWeeklyState <= StatusPrintEditWeeklyState - '1'; end if; end if; ------------------------------------------------------------------------ when others => -- state that doesn't need any dynamic text printed LCDinstruction <= NO_ACTION; active <= '0'; done <= '1'; end case; -- currentState else -- instruction_sent = '1' -- wait for ready to drop to 0 end if; elsif active = '1' and ready = '0' then -- I'm assuming that if it's active for the first time, the LCDready -- is guaranteed to be 1. LCDinstruction <= NO_ACTION; instruction_sent <= '0'; done <= '0'; else -- not start, not (active and ready), not (active and !ready) LCDinstruction <= NO_ACTION; done <= '0'; -- Added this line so MAX+plus II will quit bugging me about -- a flipflop stuck at gnd. I know it and I mean it, darnit! -- Don't worry, this line is harmless. --if currentState = INITIAL_STATE then -- LCDinstruction <= ADVANCE_CURSOR; --end if; end if; end if; -- rising edge end process specialPrinter; end printer;