-- LSI Design Contest in Okinawa 2010 -- encoder.vhd -- 2009/October/11th -- TASK: BCH(15,7) -- Copyright by Tom Wada@Univ. of the Ryukyus library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.std_logic_unsigned.all; entity ENCODER is port (SBWE : out std_logic; SB : out std_logic; START : out std_logic; RESET : in std_logic; CLK : in std_logic ); end entity ENCODER; architecture RTL of ENCODER is -- phase counts from 0 to 14 -- phase 0 to 6 : information U(X) 7 bits sent -- phase 7 to 14 : parity R(X) 8 bits sent -- phase 0 : START signal is asserted signal phase : std_logic_vector (3 downto 0); -- 7 bits information bits signal infbit : std_logic_vector (6 downto 0); -- serial info bit signal sin : std_logic; -- switchA bit signal switchA : std_logic; -- rreg signal rreg : std_logic_vector(7 downto 0); -- internal sb bit signal sbint : std_logic; -- error interval counter signal errcnt : std_logic_vector(7 downto 0); -- error signal signal errsig : std_logic; begin ------------------------------------------------ -- 0 to 14 counter ------------------------------------------------ PHASE_CNT: process(CLK,RESET) begin if (RESET='1') then phase <= "0000"; elsif (CLK'event and CLK = '1') then if (phase="1110") then -- if phase=14 phase <= "0000"; else phase <= phase + 1; end if; end if; end process PHASE_CNT; ------------------------------------------------ -- 7 bits information generation unit -- count up from 0000000 by 1 ------------------------------------------------ INF_GEN: process(CLK, RESET) begin if (RESET='1') then infbit <= "1000000"; elsif (CLK'event and CLK = '1') then if (phase="1110") then -- if phase=14 infbit <= infbit + 1; end if; end if; end process INF_GEN; ------------------------------------------------ -- internal sin generation ------------------------------------------------ SIN_GEN: process(phase, infbit) begin case phase is when "0000" => sin <= infbit(6); when "0001" => sin <= infbit(5); when "0010" => sin <= infbit(4); when "0011" => sin <= infbit(3); when "0100" => sin <= infbit(2); when "0101" => sin <= infbit(1); when "0110" => sin <= infbit(0); when others => sin <= 'X'; --others end case; end process SIN_GEN; ------------------------------------------------ -- switchA generation ------------------------------------------------ SWITCHA_GEN: process(phase) begin case phase is when "0000" => switchA <= '1'; when "0001" => switchA <= '1'; when "0010" => switchA <= '1'; when "0011" => switchA <= '1'; when "0100" => switchA <= '1'; when "0101" => switchA <= '1'; when "0110" => switchA <= '1'; when "0111" => switchA <= '0'; when "1000" => switchA <= '0'; when "1001" => switchA <= '0'; when "1010" => switchA <= '0'; when "1011" => switchA <= '0'; when "1100" => switchA <= '0'; when "1101" => switchA <= '0'; when "1110" => switchA <= '0'; when others => switchA <= 'X'; --others end case; end process SWITCHA_GEN; ------------------------------------------------ -- parity calculation ------------------------------------------------ PARITY_CAL: process(CLK, RESET) begin if (RESET='1') then rreg <= "00000000"; elsif (CLK'event and CLK = '1') then if (switchA='1') then rreg(7) <= rreg(6) xor rreg(7) xor sin; rreg(6) <= rreg(5) xor rreg(7) xor sin; rreg(5) <= rreg(4); rreg(4) <= rreg(3) xor rreg(7) xor sin; rreg(3) <= rreg(2); rreg(2) <= rreg(1); rreg(1) <= rreg(0); rreg(0) <= rreg(7) xor sin; else rreg <= rreg(6 downto 0) & '0'; end if; end if; end process PARITY_CAL; ------------------------------------------------ -- sb combinational logic ------------------------------------------------ SB_COMB: process(sin, rreg(7), switchA) begin if (switchA='1') then sbint <= sin; else sbint <= rreg(7); end if; end process SB_COMB; ------------------------------------------------ -- error interval counter ------------------------------------------------ ERR_CNT: process (CLK, RESET) begin if (RESET='1') then errcnt <= "00000000"; elsif (CLK'event and CLK = '1') then if (errcnt = "00001001") then -- max=9 (0-9) errcnt <= "00000000"; else errcnt <= errcnt +1; end if; end if; end process ERR_CNT; ------------------------------------------------ -- error signal generation ------------------------------------------------ ERROR_GEN: process (CLK, RESET) begin if (RESET='1') then errsig <= '0'; elsif (CLK'event and CLK = '1') then if (errcnt="00000000") then errsig <= '1'; -- error happens every 10 cycle else errsig <= '0'; end if; end if; end process ERROR_GEN; ------------------------------------------------ -- output signals ------------------------------------------------ SBOUT: process (CLK, RESET) begin if (RESET='1') then SB <= '0'; SBWE <='0'; elsif (CLK'event and CLK = '1') then SB <= sbint; SBWE <= sbint xor errsig; end if; end process SBOUT; STARTOUT: process (phase) begin if (phase = "0001") then START <= '1'; else START <= '0'; end if; end process STARTOUT; end architecture RTL;