DIO2 Board Projects
DIO2 Board CPLD Interface Seven-segment displays and LEDs LCD Display Pushbuttons and Switches
DIO2 circuit board block diagram
Top-level design for DIO2 interface
buff3.vhd en input output library IEEE; use IEEE.STD_LOGIC_1164.all; entity buff3 is generic (width:positive); port( input : in STD_LOGIC_vector(width-1 downto 0); en : in STD_LOGIC; output : out STD_LOGIC_vector(width-1 downto 0) ); end buff3; architecture buff3 of buff3 is begin output <= input when en = '1' else (others => 'Z'); input output
DIO2 CPLD VHDL Code library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity d2io is Port ( btns : in std_logic_vector(14 downto 0); switchs : in std_logic_vector(7 downto 0); leds : out std_logic_vector(15 downto 0); data : inout std_logic_vector(7 downto 0); addr : in std_logic_vector(5 downto 0); sseg : out std_logic_vector(6 downto 0); ssegdp : out std_logic; ssegsel : out std_logic_vector(3 downto 0); cs : in std_logic; we : in std_logic; oe : in std_logic; clk256 : in std_logic); end d2io;
architecture rtl of d2io is signal data_out : std_logic_vector(7 downto 0); signal sseg_reg : std_logic_vector(15 downto 0); signal digit : std_logic_vector(3 downto 0); signal count : unsigned(1 downto 0); signal leds_i : std_logic_vector(15 downto 0); signal strobe : std_logic; begin ssegdp <= '1'; data <= data_out when (oe = '1' and cs = '1') else (others => 'Z'); data_out <= btns(7 downto 0) when addr(1 downto 0) = "00" else '0'& btns(14 downto 8) when addr(1 downto 0) = "01" else switchs;
strobe <= cs and we; leds <= not(leds_i); process(strobe) begin if(falling_edge(strobe)) then case addr is when "000100" => leds_i(7 downto 0) <= data; when "000101" => leds_i(15 downto 8) <= data; when "000110" => sseg_reg(15 downto 8) <= data; when "000111" => sseg_reg(7 downto 0) <= data; when others => NULL; end case; end if; end process;
process(clk256) begin if(rising_edge(clk256)) then count <= count + 1; end if; end process; with count select digit <= sseg_reg(7 downto 4) when "00", sseg_reg(3 downto 0) when "01", sseg_reg(15 downto 12) when "10", sseg_reg(11 downto 8) when others; process(count) begin ssegsel <= (others => '0'); ssegsel(conv_integer(count)) <= '1'; end process;
with digit select sseg <= "1001111" when "0001", --1 "0010010" when "0010", --2 "0000110" when "0011", --3 "1001100" when "0100", --4 "0100100" when "0101", --5 "0100000" when "0110", --6 "0001111" when "0111", --7 "0000000" when "1000", --8 "0000100" when "1001", --9 "0001000" when "1010", --A "1100000" when "1011", --b "0110001" when "1100", --C "1000010" when "1101", --d "0110000" when "1110", --E "0111000" when "1111", --F "0000001" when others; --0 end rtl;
DIO2 Board CPLD Interface Seven-segment displays and LEDs LCD Display Pushbuttons and Switches
Seven-segment LED display
In opcodes.vhd constant DIO2store: opcode := X"010F"; -- DIO2! constant LCDistore: opcode := X"0110"; -- LCDinst! constant LCDdstore: opcode := X"0111"; -- LCDdata!
In wc16_control add…. signal ccycle: STD_LOGIC_VECTOR (5 downto 0); MultiCC: process (clk, clr, current_state) begin if clr = '1' then ccycle <= "000001"; elsif (clk'event and clk = '1') then if current_state = exec then ccycle <= ccycle + 1; else end if; end process MultiCC;
In wc16_control add…. when exec => -- execute instr without fetching next one if (icode = X"010E" or icode = X"010F") and ccycle < 3 then next_state <= exec; elsif (icode = X"0110" or icode = X"0111") and ccycle < 8 then --elsif icode = X"Code_for_multi-cycle" -- and ccycle < Num_cc_to_exec then -- next_state <= exec; else next_state <= fetch; -- go to fetch state end if;
In wc16_control add…. DIO2! ( data addr .. ) when DIO2store => cs <= '1'; oe <= '0'; pinc <= '0'; if ccycle = 1 then we <= '1'; else tload <= '1'; nload <= '1'; tsel <= "111"; nsel <= "01"; dpop <= '1'; end if;
D2DIGstore.whp \ Test of DIO2 DIG! : D2DIG! ( n -- ) : D2DIG! ( n -- ) DUP 8 RSHIFT \ n nHI 7 DIO2! \ display nHI 6 DIO2! ; \ display nLO : main ( -- ) BEGIN waitB4 S@ \ get HI byte DUP DIG! 8 LSHIFT waitB4 S@ \ get LO byte OR D2DIG! AGAIN ;
LED16.whp \ led16.whp HEX : 1ms_Delay ( -- ) 30D1 FOR NEXT ; : 1ms_Delay ( -- ) 30D1 FOR NEXT ; : .5sec_Delay ( -- ) 1F4 FOR 1ms_Delay NEXT ; : D2DIG! ( n -- ) DUP 8 RSHIFT \ n nHI 7 DIO2! \ display nHI 6 DIO2! ; \ display nLO : D2LD! ( n -- ) 5 DIO2! \ display nHI 4 DIO2! ; \ display nLO LED16.whp
LED16.whp (cont.) : MAIN ( -- ) BEGIN 8000 10 FOR DUP D2LD! DUP D2DIG! .5sec_Delay 2/ NEXT U2/ DROP AGAIN ;
DIO2 Board CPLD Interface Seven-segment displays and LEDs LCD Display Pushbuttons and Switches
DIO2 circuit board block diagram
In wc16_control add…. LCDinst! ( data 0 .. ) LCDdata! ( data 0 .. ) when LCDistore => LCD_RW <= '0'; LCD_RS <= '0'; pinc <= '0'; if ccycle < 7 then LCD_E <= '1'; else tload <= '1'; nload <= '1'; tsel <= "111"; nsel <= "01"; dpop <= '1'; end if; LCDdata! ( data 0 .. ) when LCDdstore => LCD_RW <= '0'; LCD_RS <= '1'; pinc <= '0'; if ccycle < 7 then LCD_E <= '1'; else tload <= '1'; nload <= '1'; tsel <= "111"; nsel <= "01"; dpop <= '1'; end if;
Lcd3.whp \ LCD for Digilab DIO2 \ LCD3.WHP HEX : 1ms_Delay ( -- ) HEX : 1ms_Delay ( -- ) 30D1 FOR NEXT ; : 30ms.Delay ( -- ) 1E FOR 1ms_Delay NEXT ; : hex2asc ( n -- asc ) 0F AND \ mask upper nibble DUP 9 > \ if n > 9 IF 37 + \ add $37 ELSE 30 + \ else add $30 THEN ;
Lcd3.whp : lcd.init ( -- ) 30ms.delay 3C 0 LCDinst! \ 2 x 40 display 0f 0 LCDinst! \ display on 1 0 LCDinst! \ display clear 1ms_Delay 1ms_Delay 6 0 LCDinst! \ entry cursor shift off ;
Lcd3.whp : hex>lcd ( hex -- ) HEX2ASC 0 LCDdata! 30ms.delay; : u.lcd ( u -- ) \display T on LCD DUP C RSHIFT hex>lcd DUP 8 RSHIFT DUP 4 RSHIFT hex>lcd ;
Lcd3.whp : MAIN ( -- ) lcd.init BEGIN waitB4 S@ \ get high byte DUP DIG! DUP hex>lcd 8 LSHIFT waitB4 S@ \ get low byte OR waitB4 u.lcd \ display on lcd AGAIN ;
DIO2 Board CPLD Interface Seven-segment displays and LEDs LCD Display Pushbuttons and Switches
Top-level design for DIO2 interface data_io
From DIO2 CPLD data_out <= btns(7 downto 0) when addr(1 downto 0) = "00" else '0'& btns(14 downto 8) when addr(1 downto 0) = "01" else switchs; In opcodes.vhd constant DIO2fetch: opcode := X"003A"; -- DIO2@ In wc16_control.vhd when DIO2fetch => -- read 8-bit DIO2-bus (E1) tload <= '1'; -- DIO2@ ( addr – data ) tsel <= "100"; cs <= '1'; oe <= '1'; In Lab9.vhd E1 <= ground & data_io; data <= data_io;
SW2test.whp \ Test of DIO2 switches : main ( -- ) BEGIN : main ( -- ) BEGIN 3 DIO2@ \ read switches 4 DIO2! \ display on LD(7:0) AGAIN ;
BTN2test.whp \ Test of DIO2 buttons : D2DIG! ( n -- ) : D2DIG! ( n -- ) DUP 8 RSHIFT \ n nHI 7 DIO2! \ display nHI 6 DIO2! ; \ display nLO : D2LD! ( n -- ) 5 DIO2! \ display nHI 4 DIO2! ; \ display nLO : main ( -- ) BEGIN 1 DIO2@ \ btns(15:8) 8 LSHIFT 0 DIO2@ \ btns(7:0) OR DUP DIG! DUP D2DIG! D2LD! AGAIN ;
BTN2test2.whp \ Test of DIO2 buttons : get.BTN2 ( -- n ) : get.BTN2 ( -- n ) 1 DIO2@ \ btns(15:8) 8 LSHIFT 0 DIO2@ \ btns(7:0) OR ; : main2 ( -- ) BEGIN BEGIN \ wait to lift finger get.BTN2 0= UNTIL BEGIN \ wait to press button get.BTN2 get.BTN2 \ get button DUP DIG! DUP D2DIG! D2LD! AGAIN ;
DigScroll
Random Number Generator
RAM Module – Coregen IP
WHYP words to read and write data to memory ! ( data addr -- ) \ “store” data at addr @ ( addr – data ) \ “fetch” data from addr
! ( data addr -- ) \ “store” data at addr when store => tload <= '1'; nload <= '1'; tsel <= "111"; nsel <= "01"; dpop <= '1'; if ccycle = "000001" then pinc <= '0'; we <= '1'; end if;
In wc16_control add…. Store (!) when exec => -- execute instr without fetching next one if (icode = X"010E" or icode = X"010F") and ccycle < 3 then next_state <= exec; elsif (icode = X"0110" or icode = X"0111") and ccycle < 8 then --elsif icode = X"Code_for_multi-cycle" -- and ccycle < Num_cc_to_exec then -- next_state <= exec; else next_state <= fetch; -- go to fetch state end if;
@ ( addr – data ) \ “fetch” data from addr when ramfetch => -- read RAM in E1 tload <= '1'; tsel <= "100";
Hex to Decimal h1 h2 h3 h4 d1 d2 d3 d4 H2D ( h – d ) Hex Decimal Push each decimal digit into stack. \ d4 d3 d2 d1 4 LSHIFT and + \ (d4 + 10 (d3 + 10 (d2 + 10 * d1 ) ) ) d1 d2 d3 d4 Decimal
Hex to Decimal : H2D ( h - d ) \ convert hex to decimal 0 a UM/MOD \ get & push decimal digit 0 a UM/MOD 0 a UM/MOD \ d4 d3 d2 d1 4 LSHIFT + \ put in the right place 4 LSHIFT + 4 LSHIFT + ; \ (d4 + 10 (d3 + 10 (d2 + 10 * d1 ) ) )
Example: 5678 dec = 162Eh HEX : H2D ( h - d ) \ convert hex to decimal 0 a UM/MOD \ 8 237 0 a UM/MOD \ 8 7 38 0 a UM/MOD \ 8 7 6 5 4 LSHIFT + \ 8 7 56 4 LSHIFT + \ 8 567 4 LSHIFT + ; \ 5678
Decimal to Hex d1 d2 d3 d4 h1 h2 h3 h4 D2H ( d – h) Decimal Hex Push each digit into stack. \ d4 d3 d2 d1 Multiply, drop and + \ ( d4 + a ( d3 + a ( d2 + a * d1 ) ) ) . 50 h1 h2 h3 h4 Hex
Decimal to Hex : D2H ( d - h ) \ convert decimal to hex 0 10 UM/MOD \ push decimal digit to stack 0 10 UM/MOD 0 10 UM/MOD \ d4 d3 d2 d1 a UM* drop + \ multiply digit by a a UM* drop + a UM* drop + ; \ ( d4 + a ( d3 + a ( d2 + a * d1 ) ) )
Example: 5678 dec = 162Eh HEX : D2H ( d - h ) \ convert decimal to hex \ 5678 0 10 UM/MOD \ 8 567 0 10 UM/MOD \ 8 7 56 0 10 UM/MOD \ 8 7 6 5 a UM* drop + \ 8 7 38 a UM* drop + \ 8 237 a UM* drop + ; \ 162E