OpenCores
URL https://opencores.org/ocsvn/manchesterwireless/manchesterwireless/trunk

Subversion Repositories manchesterwireless

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /manchesterwireless
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/globals.vhd
0,0 → 1,17
library ieee;
use ieee.std_logic_1164.all;
 
package globals is
-- number of data bits
constant WORD_LENGTH : integer := 4;
 
-- when each transmitter bit is 3.24 ms and the FPGA clock is 50 MHz
constant MAX_COUNT: integer := 2**18-1;
-- double is nominally 43000-50000
constant INTERVAL_MAX_DOUBLE: integer := 120000;
constant INTERVAL_MIN_DOUBLE: integer := 90000;--80000
-- single is nominally 23200
constant INTERVAL_MAX_SINGLE: integer := 65000;
constant INTERVAL_MIN_SINGLE: integer := 10000;
constant INTERVAL_QUADRUPLE: integer := 650000;--350000
end globals;
trunk/globals.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/synthTest.vhd =================================================================== --- trunk/synthTest.vhd (nonexistent) +++ trunk/synthTest.vhd (revision 2) @@ -0,0 +1,91 @@ +library ieee; +use ieee.std_logic_1164.all; + +use work.globals.all; + +entity synthTest is + port ( + clk_i : in std_logic; + rst_i : in std_logic; + data_i : in std_logic; + ready_o : out std_logic; + character_o : out std_logic_vector(0 to 7); + anode_ctrl : out std_logic_vector(3 downto 0); + recieved_debug : out std_logic_vector(3 downto 0); + waitforstart_rdy : out std_logic; + testpin : out std_logic + ); +end synthTest; + +architecture Behavioral of synthTest is + + component decodeManchester + port ( + clk_i : in std_logic; + rst_i : in std_logic; + data_i : in std_logic; + q_o : out std_logic_vector(WORD_LENGTH-1 downto 0); + ready_o : out std_logic; + recieved_debug : out std_logic_vector(3 downto 0); + waitforstart_rdy : out std_logic + ); + end component; + + signal decode_output : std_logic_vector(WORD_LENGTH-1 downto 0); + -- up/down and left/right buffers + signal ud_buff1, ud_buff1_reg : std_logic_vector(6 downto 0); + signal reset_manchester, soft_reset, ready_o_buff : std_logic; +begin + character_o(7) <= '1'; -- turn off decimal point + testpin <= '1'; + + reset_manchester <= rst_i or soft_reset; + ready_o <= ready_o_buff; + + inst_decodeManchester: decodeManchester + port map( + clk_i => clk_i, + rst_i => reset_manchester, + data_i => data_i, + q_o => decode_output, + ready_o => ready_o_buff, + recieved_debug => recieved_debug, + waitforstart_rdy => waitforstart_rdy + ); + + -- decode up/down first digit (ones place) + with decode_output(3 downto 0) select + ud_buff1 <= "0000001" when x"0", -- off + "1001111" when x"1", -- 1 + "0010010" when x"2", -- 2 + "0000110" when x"3", -- 3 + "1001100" when x"4", -- 4 + "0100100" when x"5", -- 5 + "0100000" when x"6", -- 6 + "0001111" when x"7", -- 7 + "0000000" when x"8", -- 8 + "0000100" when x"9", -- 9 + "0110000" when others; -- Error + + process (clk_i,rst_i) + begin + if rst_i = '1' then + soft_reset <= '0'; + ud_buff1_reg <= "1111111"; + elsif (clk_i'event and clk_i = '1') then + -- register the output + if (ready_o_buff = '1') then + ud_buff1_reg <= ud_buff1; + soft_reset <= '1'; + else + soft_reset <= '0'; + end if; + + end if; + end process; + + character_o(0 to 6) <= ud_buff1_reg; + anode_ctrl <= "0111"; + +end Behavioral; +
trunk/synthTest.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/md16/md16.vhd =================================================================== --- trunk/md16/md16.vhd (nonexistent) +++ trunk/md16/md16.vhd (revision 2) @@ -0,0 +1,176 @@ +----------------------------------------------------------------------------- +-- Copyright (C) 2009 José Rodríguez-Navarro +-- +-- This code is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. +-- +-- This code is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- +-- md16.vhd +-- +-- Manchester Decoding based on Oversampling & Counting Algorithm +-- +-- Revision Date Author Comment +-- -------- ---------- -------------------- ---------------- +-- 1.0 20/02/09 J. Rodriguez-Navarro Initial revision +-- 2.0 15/05/09 S. Green Reduced scope +----------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.globals.all; + +-------------------------------------------------------------------------------- + +entity md16 is + port ( + clk_i : in std_logic; + ce_i : in std_logic; + rst_i : in std_logic; + data_i : in std_logic; + q_o : out std_logic_vector(3 downto 0); + ready_o : out std_logic + ); +end md16; + +-------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- + +architecture inst_md16 of md16 is + +signal transition_n: std_logic; +signal transition_i: std_logic; + +signal count_ones : integer range 0 to MAX_COUNT; +signal count_ones_n : integer range 0 to MAX_COUNT; +signal count_zeros : integer range 0 to MAX_COUNT; +signal count_zeros_n : integer range 0 to MAX_COUNT; + +signal single_one: std_logic; +signal double_one: std_logic; +signal single_zero: std_logic; +signal double_zero: std_logic; + +signal data_i_d : std_logic; +signal data_i_d2 : std_logic; +signal data_i_d3 : std_logic; +signal data_i_d3b: std_logic; + +begin + +-------------------------------------------------------------------------------- +-- SEQUENTIAL ------------------------------------------------------------------ +-------------------------------------------------------------------------------- + +-- Domain Clock (clk_i) +process (rst_i, clk_i) +begin + + if rst_i = '1' then + data_i_d <= '1'; + data_i_d2 <= '1'; + data_i_d3 <= '1'; + transition_i <= '0'; + count_ones <= 0; + count_zeros <= 0; + elsif (rising_edge(clk_i) and ce_i = '1') then -- posedge + data_i_d3 <= data_i_d2; + data_i_d2 <= data_i_d; + data_i_d <= data_i; + transition_i <= transition_n; + count_ones <= count_ones_n; + count_zeros <= count_zeros_n; + end if; + +end process; + + +-------------------------------------------------------------------------------- +-- COMBINATIONAL --------------------------------------------------------------- +-------------------------------------------------------------------------------- + +-- Mark transition when an edge on data_i is detected +transition_n <= data_i_d xor data_i_d2; +ready_o <= transition_i; -- buffered transition_n + +-- Invert and count zeroes +data_i_d3b <= not data_i_d3; + +-- +-- Increment counters between transitions every posedge clk_i +-- +process (transition_i, data_i_d3, data_i_d3b, count_ones, count_zeros) +begin + + if transition_i = '1' then + count_ones_n <= 0; + count_zeros_n <= 0; + else + count_ones_n <= count_ones + conv_integer(data_i_d3); + count_zeros_n <= count_zeros + conv_integer(data_i_d3b); + end if; + +end process; + +-- +-- map single/double one/zero to output +-- +process (transition_i, rst_i) +begin + + if (rst_i = '1') then + q_o <= "0000"; -- protocol dictates an inital one. used in connecting entity + elsif rising_edge(transition_i) then + q_o(0) <= single_one; + q_o(1) <= double_one; + q_o(2) <= single_zero; + q_o(3) <= double_zero; + end if; + +end process; + +-- +-- unsigned comparators +-- +process(count_ones) +begin + + if (count_ones >= INTERVAL_MIN_DOUBLE) and (count_ones <= INTERVAL_MAX_DOUBLE) then + double_one <= '1'; + else + double_one <= '0'; + end if; + if (count_ones >= INTERVAL_MIN_SINGLE) and (count_ones <= INTERVAL_MAX_SINGLE) then + single_one <= '1'; + else + single_one <= '0'; + end if; + +end process; + +process(count_zeros) +begin + + if (count_zeros >= INTERVAL_MIN_DOUBLE) and (count_zeros <= INTERVAL_MAX_DOUBLE) then + double_zero <= '1'; + else + double_zero <= '0'; + end if; + if (count_zeros >= INTERVAL_MIN_SINGLE) and (count_zeros <= INTERVAL_MAX_SINGLE) then + single_zero <= '1'; + else + single_zero <= '0'; + end if; + +end process; + + +end; + +
trunk/md16/md16.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/md16/simTest.vhd =================================================================== --- trunk/md16/simTest.vhd (nonexistent) +++ trunk/md16/simTest.vhd (revision 2) @@ -0,0 +1,88 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + + +entity test_sim is +end test_sim; + +architecture Behavioral of test_sim is + + COMPONENT md16 + PORT( + clk_i : in std_logic; + ce_i : in std_logic; + rst_i : in std_logic; + data_i : in std_logic; + q_o : out std_logic_vector(3 downto 0); + ready_o : out std_logic + ); + END COMPONENT; + + signal clk : std_logic := '0'; + signal ce_i : std_logic := '0'; + signal mdi : std_logic := '0'; + signal q : std_logic_vector(3 downto 0); + signal nd : std_logic; + + constant period : time := 10 ns; + constant md_period : time := period*16; + signal reset : std_logic := '1'; +begin + + Inst_md16: md16 PORT MAP( + clk_i => clk, + ce_i => ce_i, + rst_i => reset, + data_i => mdi, + q_o => q, + ready_o => nd + ); + + process + begin + loop + reset <= '1'; + ce_i <= '0'; + + wait for 2*md_period; + + reset <= '0'; + ce_i <= '1'; + + wait for 2*md_period; + + mdi <= not mdi; + wait for 2*md_period; + + mdi <= not mdi; + wait for md_period; + + mdi <= not mdi; + wait for md_period; + + mdi <= not mdi; + wait for md_period; + + mdi <= not mdi; + wait for 2*md_period; + + mdi <= not mdi; + wait for md_period; + + mdi <= not mdi; + wait for 5*md_period; + end loop; + end process; + + process + begin + loop + clk <= not clk; + wait for period/2; + end loop; + end process; + +end Behavioral; +
trunk/md16/simTest.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/simTest.vhd =================================================================== --- trunk/simTest.vhd (nonexistent) +++ trunk/simTest.vhd (revision 2) @@ -0,0 +1,224 @@ +library ieee; +use ieee.std_logic_1164.all; + +use work.globals.all; + +entity testSim is +end testSim; + +architecture Behavioral of testSim is + + component decodeManchester + port ( + clk_i : in std_logic; + rst_i : in std_logic; + data_i : in std_logic; + q_o : out std_logic_vector(WORD_LENGTH-1 downto 0); + ready_o : out std_logic; + recieved_debug : out std_logic_vector(3 downto 0); + waitforstart_rdy : out std_logic + ); + end component; + + signal decode_output : std_logic_vector(WORD_LENGTH-1 downto 0); + -- up/down and left/right buffers + signal parity_o_buff, parity_o_reg : std_logic; + signal button_o_buff, button_o_reg : std_logic_vector(1 downto 0); + signal ud_buff1, ud_buff2, lr_buff1, lr_buff2 : std_logic_vector(6 downto 0); + signal ud_buff1_reg, ud_buff2_reg, lr_buff1_reg, lr_buff2_reg : std_logic_vector(6 downto 0); + signal char_select : integer range 0 to 3; + signal reset_manchester, soft_reset, ready_o_buff : std_logic; + + + signal clk_i : std_logic; + signal rst_i : std_logic := '1'; + signal data_i : std_logic; + signal ready_o : std_logic; + signal character_o : std_logic_vector(0 to 7); + signal anode_ctrl : std_logic_vector(3 downto 0); + signal button_o : std_logic_vector(1 downto 0); + signal parity_o : std_logic; + signal recieved_debug : std_logic_vector(3 downto 0); + signal waitforstart_rdy : std_logic; + + signal coded_rdy: std_logic; + signal coded : std_logic_vector(WORD_LENGTH-1 downto 0); + constant half_period : time := 10 ns; + constant period : time := 2*half_period; + constant mid_single : time := (INTERVAL_MIN_SINGLE+INTERVAL_MAX_SINGLE)/2*period; + constant WORD : std_logic_vector(28 downto 0) := "01100101100101010101010101010"; + +begin + character_o(7) <= '1'; -- turn off decimal point + + reset_manchester <= rst_i or soft_reset; + ready_o <= ready_o_buff; + + inst_decodeManchester: decodeManchester + port map( + clk_i => clk_i, + rst_i => reset_manchester, + data_i => data_i, + q_o => decode_output, + ready_o => ready_o_buff, + recieved_debug => recieved_debug, + waitforstart_rdy => waitforstart_rdy + ); + + -- the transmitter is sending the following UP/DOWN (4 bits) + -- then left/right (3 bits), and finally the parity (1 bit) + -- each command was ror onto the transmitter -- one at a time. + -- the decoder was written to assume that all the data was in + -- being shifted to the transmitter from the right + -- thus, while we are transmitting: + -- initialize|up/down|left/right|buttons|parity|stop + -- the decoder will return results to us as + -- parity|buttons|left/right|up/down + -- bits 9| 8-7 | 6-4 | 3-0 + + -- decode up/down first digit (ones place) + with decode_output(3 downto 0) select + ud_buff1 <= "0000001" when x"D", -- off + "1001111" when x"F", -- 1 + "0010010" when x"7", -- 2 + "0000110" when x"5", -- 3 + "1001100" when x"1", -- 4 + "0100100" when x"3", -- 5 + "0100000" when x"2", -- 6 + "0001111" when x"6", -- 7 + "0000000" when x"e", -- 8 + "0000100" when x"c", -- 9 + "0000001" when x"a", -- 10 + "1001111" when x"b", -- 11 + "0010010" when x"9", -- 12 + "0000110" when x"8", -- 13 + "1111111" when others; -- 'E'rror + + -- decode up/down second digit (tens place) + with decode_output(3 downto 0) select + ud_buff2 <= "1001111" when x"a", -- 10 + "1001111" when x"b", -- 11 + "1001111" when x"9", -- 12 + "1001111" when x"8", -- 13 + "1111111" when others; + + -- decode left/right first digit + with decode_output(6 downto 4) select + lr_buff1 <= "1001111" when "010", -- -1 + "0010010" when "011", -- -2 + "0000110" when "001", -- -3 + "0000001" when "110", -- 0 + "1001111" when "100", -- 1 + "0010010" when "101", -- 2 + "0000110" when "111", -- 3 + "1111111" when others; + + -- decode left/right sign digit + with decode_output(6 downto 4) select + lr_buff2 <= "1111110" when "010", -- -1 + "1111110" when "011", -- -2 + "1111110" when "001", -- -3 + "1111111" when others; + + -- decode buttons + with decode_output(8 downto 7) select + button_o_buff <= "11" when "10", -- 00 + "01" when "11", -- 10 + "10" when "01", -- 01 + "00" when "00", -- 11 + "11" when others; + + parity_o_buff <= decode_output(9); + parity_o <= parity_o_reg; + + process (clk_i,rst_i) + variable counter : integer range 0 to 1023; + begin + if rst_i = '1' then + char_select <= 0; + counter := 0; + div_clk := '0'; + soft_reset <= '0'; + elsif (clk_i'event and clk_i = '1') then + -- register the output + if (ready_o_buff = '1') then + ud_buff1_reg <= ud_buff1; + ud_buff2_reg <= ud_buff2; + lr_buff1_reg <= lr_buff1; + lr_buff2_reg <= lr_buff2; + button_o_reg <= button_o_buff; + parity_o_reg <= parity_o_buff; + soft_reset <= '1'; + else + soft_reset <= '0'; + end if; + + counter := counter + 1; + if (counter = 1023) then + + -- this is for simulation + -- ModelSim does not want to roll over + if char_select < 3 then + char_select <= char_select + 1; + else + char_select <= 0; + end if; + + counter := 0; + end if; + + end if; + end process; + + -- set output + with char_select select + character_o(0 to 6) <= ud_buff2_reg when 0, + ud_buff1_reg when 1, + lr_buff2_reg when 2, + lr_buff1_reg when 3; + + with char_select select + anode_ctrl <= "0111" when 0, + "1011" when 1, + "1101" when 2, + "1110" when 3; + + process + begin + wait for 5*period; + rst_i <= '0'; + + -- begin transmission header + data_i <= '1'; + wait for 5*MID_SINGLE; + + data_i <= '0'; + wait for MID_SINGLE; + -- end transmission header + + for i in WORD'left downto 0 loop + data_i <= WORD(i); + wait for MID_SINGLE; + end loop; + + data_i <= '1'; + wait for MID_SINGLE; + + rst_i <= '1'; + wait for 5*period; + + end process; + + clock : process + begin + clk_i <= '1'; + loop + wait for half_period; + clk_i <= not clk_i; + end loop; + end process; + +end Behavioral; + + +
trunk/simTest.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/waitForStart/simTest.vhd =================================================================== --- trunk/waitForStart/simTest.vhd (nonexistent) +++ trunk/waitForStart/simTest.vhd (revision 2) @@ -0,0 +1,62 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity testSim is +end testSim; + +architecture Behavioral of testSim is + constant start_length : integer := 20; + + component waitForStart + generic (start_length : integer); + port ( + data_i : in std_logic; + clk_i : in std_logic; + rst_i : in std_logic; + ready_o : out std_logic + ); + end component; + + constant half_period : time := 10 ns; + + signal data_i : std_logic; + signal clk_i : std_logic; + signal rst_i : std_logic := '1'; + signal ready_o : std_logic; +begin + + process + begin + rst_i <= '1'; + wait for 5 ns; + rst_i <= '0'; + data_i <= '1'; + + wait for 400 ns; + data_i <= '0'; + + wait for 100 ns; + data_i <= '1'; + + wait for 2000 ns; + end process; + + waitForStart1 : waitForStart + generic map(start_length => start_length) + port map( + data_i => data_i, + clk_i => clk_i, + rst_i => rst_i, + ready_o => ready_o + ); + + clock : process + begin + clk_i <= '1'; + loop + wait for half_period; + clk_i <= not clk_i; + end loop; + end process; +end Behavioral; +
trunk/waitForStart/simTest.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/waitForStart/waitForStart.vhd =================================================================== --- trunk/waitForStart/waitForStart.vhd (nonexistent) +++ trunk/waitForStart/waitForStart.vhd (revision 2) @@ -0,0 +1,61 @@ +----------------------------------------------------------------------------- +-- Copyright (C) 2009 Sam Green +-- +-- This code is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. +-- +-- This code is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- +-- +-- Revision Date Author Comment +-- -------- ---------- -------------------- ---------------- +-- 1.0 09/06/09 S. Green Initial version +----------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.globals.all; + +entity waitForStart is + port ( + data_i : in std_logic; + clk_i : in std_logic; + rst_i : in std_logic; + ready_o : out std_logic + ); +end waitForStart; + +architecture behavioral of waitForStart is +begin + process (clk_i, rst_i) + variable counter : integer; + variable lock : std_logic; + begin + if (rst_i = '1') then + ready_o <= '0'; + counter := 0; + lock := '0'; + elsif rising_edge(clk_i) then + if data_i = '1' then + counter := counter + 1; + else + counter := 0; + end if; + + if counter > INTERVAL_QUADRUPLE or lock = '1' then + ready_o <= '1'; + lock := '1'; + else + ready_o <= '0'; + end if; + end if; + end process; + + end behavioral; +
trunk/waitForStart/waitForStart.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/readme.txt =================================================================== --- trunk/readme.txt (nonexistent) +++ trunk/readme.txt (revision 2) @@ -0,0 +1,11 @@ +Usage: + +Open globals.vhd. Change WORD_LENGTH to the number of bits to be received -- this is the number of bits _before_ Manchester encoding. + +The constants: INTERVAL_MAX_DOUBLE, INTERVAL_MIN_DOUBLE, INTERVAL_MAX_SINGLE, INTERVAL_MIN_SINGLE, INTERVAL_QUADRUPLE set the window of FPGA clocks needed to classify a single/double one/zero. For example, if transmission arrives at 1K BAUD, then each bit is 1ms long. If the FPGA clock is 50MHz, giving a period of 2E-8, then 50K FPGA clocks will occur each bit. Therefore set INTERVAL_MIN/MAX_SINGLE to be somewhere on either end of 50K, for example 10K and 75K. Do similar for INTERVAL_MIN/MAX_DOUBLE. Unfortunately, you will probably need to experiment to see how static your transmitter BAUD really is. + +Out of the box, the decodeManchester core will decode one transmission, then stop, waiting to be reset, until the next signal is decodable. See synthTest.vhd for a simple way to reset the circuit after each received bit. + +TODO: + +When testing this circuit with an ASK transmitter/receiver pair, random radio noise was a huge problem. There needs to be a way to strengthen the protocol. Also, I believe, it is from the quality of the ASK equipment, the twoToOne subcore misses some bits, causing frustrating noise to be permitted into the system. \ No newline at end of file
trunk/readme.txt Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/decodeManchester.vhd =================================================================== --- trunk/decodeManchester.vhd (nonexistent) +++ trunk/decodeManchester.vhd (revision 2) @@ -0,0 +1,109 @@ +----------------------------------------------------------------------------- +-- Copyright (C) 2009 Sam Green +-- +-- This code is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. +-- +-- This code is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- +-- +-- Revision Date Author Comment +-- -------- ---------- -------------------- ---------------- +-- 1.0 09/06/09 S. Green Initial version +----------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +use work.globals.all; + +entity decodeManchester is + port ( + clk_i : in std_logic; + rst_i : in std_logic; + data_i : in std_logic; + q_o : out std_logic_vector(WORD_LENGTH-1 downto 0); + ready_o : out std_logic; + recieved_debug : out std_logic_vector(3 downto 0); + waitforstart_rdy : out std_logic + ); +end decodeManchester; + +architecture behavioral of decodeManchester is + + component waitForStart + port ( + data_i : in std_logic; + clk_i : in std_logic; + rst_i : in std_logic; + ready_o : out std_logic + ); + end component; + + component md16 + port ( + clk_i : in std_logic; + ce_i : in std_logic; + rst_i : in std_logic; + data_i : in std_logic; + q_o : out std_logic_vector(3 downto 0); + ready_o : out std_logic + ); + end component; + + component twoToOne + port ( + clk_i : in std_logic; + rst_i : in std_logic; + nd_i : in std_logic; + encoded_i : in std_logic_vector(3 downto 0); + decoded_o : out std_logic_vector(WORD_LENGTH-1 downto 0); + nd_o : out std_logic + ); + end component; + + signal wait_rdy : std_logic; + signal md16_nd : std_logic; + signal md16_q_o : std_logic_vector(3 downto 0); + +begin + + inst_waitForStart: waitForStart + port map( + data_i => data_i, + clk_i => clk_i, + rst_i => rst_i, + ready_o => wait_rdy + ); + + waitforstart_rdy <= wait_rdy; + + inst_md16: md16 + port map( + clk_i => clk_i, + ce_i => wait_rdy, + rst_i => rst_i, + data_i => data_i, + q_o => md16_q_o, + ready_o => md16_nd + ); + + recieved_debug <= md16_q_o; + + inst_twoToOne: twoToOne + port map( + clk_i => clk_i, + rst_i => rst_i, + nd_i => md16_nd, + encoded_i => md16_q_o, + decoded_o => q_o, + nd_o => ready_o + ); + +end behavioral; +
trunk/decodeManchester.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/twoToOne/simTest.vhd =================================================================== --- trunk/twoToOne/simTest.vhd (nonexistent) +++ trunk/twoToOne/simTest.vhd (revision 2) @@ -0,0 +1,257 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +use work.globals.all; + +entity sim_test is +end sim_test; + +architecture Behavioral of sim_test is + + COMPONENT twoToOne + PORT( + clk_i : in std_logic; + rst_i : in std_logic; + encoded_i : in std_logic_vector(3 downto 0); + nd_i : in std_logic; + decoded_o : out std_logic_vector(WORD_LENGTH-1 downto 0); + nd_o : out std_logic + ); + END COMPONENT; + +-- For encoded_i: +-- +-- 0000 = null +-- 0001 = single one +-- 0010 = single zero +-- 0100 = double one +-- 1000 = double zero + + signal clk_i : std_logic; + signal rst_i : std_logic; + signal encoded_i : std_logic_vector(3 downto 0) := "0000"; + signal nd_i : std_logic := '0'; + signal decoded_o : std_logic_vector(WORD_LENGTH-1 downto 0); + signal nd_o : std_logic; + constant half_period : time := 10 ns; + constant period : time := 2*half_period; + constant mid_single : time := (INTERVAL_MIN_SINGLE+INTERVAL_MAX_SINGLE)/2*period; + +begin + + Inst_twoToOne: twoToOne PORT MAP( + clk_i => clk_i, + rst_i => rst_i, + encoded_i => encoded_i, + nd_i => nd_i, + decoded_o => decoded_o, + nd_o => nd_o + ); + + process + begin +-- below never changes + rst_i <= '1'; + wait for MID_SINGLE; + + rst_i <= '0'; + encoded_i <= "0000"; + wait for MID_SINGLE; + + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "1000"; -- 00 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + +-- above never changes + + encoded_i <= "0010"; --11 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0100"; --0 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0001"; --1 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "1000"; --00 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + + encoded_i <= "0001"; --1 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0100"; --0 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0001"; --1 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0100"; --0 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0001"; --1 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0100"; --0 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0001"; --1 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0100"; --0 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0001"; --1 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0100"; --0 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0001"; --1 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0100"; --0 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + + + + + encoded_i <= "0001"; --1 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0100"; --0 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0001"; --1 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + encoded_i <= "0100"; --0 + + nd_i <= '1'; + wait for period; + nd_i <= '0'; + + wait for MID_SINGLE; + + end process; + + clock : process + begin + clk_i <= '1'; + loop + wait for half_period; + clk_i <= not clk_i; + end loop; + end process; + +end Behavioral; +
trunk/twoToOne/simTest.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: trunk/twoToOne/twoToOne.vhd =================================================================== --- trunk/twoToOne/twoToOne.vhd (nonexistent) +++ trunk/twoToOne/twoToOne.vhd (revision 2) @@ -0,0 +1,225 @@ +----------------------------------------------------------------------------- +-- Copyright (C) 2009 Sam Green +-- +-- This code is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. +-- +-- This code is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- +-- twoToOne.vhd +-- +-- Revision Date Author Comment +-- -------- ---------- -------------------- ---------------- +-- 1.0 09/06/09 S. Green Initial version +----------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +use work.globals.all; + +-- For encoded_i: +-- +-- 0000 = null +-- 0001 = single one +-- 0010 = double one +-- 0100 = single zero +-- 1000 = double zero + +entity twoToOne is + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + nd_i : in std_logic; + encoded_i : in std_logic_vector(3 downto 0); + decoded_o : out std_logic_vector(WORD_LENGTH-1 downto 0); + nd_o : out std_logic + ); + +end twoToOne; + +architecture Behavioral of twoToOne is + + type state_type is (reset, pause, one_0, one_1, two_0, two_1); + signal state, next_state : state_type; + + -- *2 comes from each bit in the word is manchester encoded. + -- +2 comes from protocol transmitting -------_ to initiate + -- a transmission + constant STRING_LENGTH : integer := WORD_LENGTH*2+2; + -- the range -1 comes from the state machine which will + -- update index_n while the protocol finishes transmission + signal index, index_n : integer range -1 to STRING_LENGTH-1; + signal str_buffer : std_logic_vector(STRING_LENGTH-3 downto 0); + signal insert : std_logic_vector(1 downto 0); + signal nd_o_buff : std_logic; +begin + + process(nd_i, rst_i) + begin + if rst_i = '1' then + + index <= STRING_LENGTH-1; + state <= reset; + str_buffer <= (others => '0'); + nd_o_buff <= '0'; + + elsif rising_edge(nd_i) then + -- index is initalized at STRING_LENGTH-1 + -- the protocol initializes with two bits + -- which are trashed, hence we wait until the first + -- trashed bits have been passed + -- + -- processing stops when the WORD_LENGTH bits have arrived (nd_o_buff = '1') + if STRING_LENGTH - index >= 3 and nd_o_buff = '0' then + -- update one or two? + if index - index_n = 2 then -- update 2 + str_buffer(index downto index-1) <= insert; + else -- update 1 + str_buffer(index) <= insert(1); + end if; + end if; + + -- finished? + if index = 0 then + nd_o_buff <= '1'; + state <= reset; + else + index <= index_n; + state <= next_state; + end if; + end if; + end process; + + output_decode: process(state, index, nd_i) + begin + case state is + + when one_1 => + insert <= "10"; + if (index > -1) then + index_n <= index - 1; + else + index_n <= 0; -- error + end if; + + when one_0 => + insert <= "00"; + if (index > -1) then + index_n <= index - 1; + else + index_n <= 0; -- error + end if; + + when two_1 => + insert <= "11"; + + if (index > 0) then + index_n <= index - 2; + else + index_n <= 0; -- error + end if; + + when two_0 => + insert <= "00"; + + if (index > 0) then + index_n <= index - 2; + else + index_n <= 0; -- error + end if; + + when others => + insert <= "00"; + index_n <= index; + + end case; + end process; + + next_state_decode: process(state, encoded_i) + begin + next_state <= state; + case(state) is + when reset => + + next_state <= pause; + + when pause => + + next_state <= one_1; -- only if we came from reset + + when one_0 => + + case(encoded_i) is + when "0100" => next_state <= one_0; -- remain here until change + when "0001" => next_state <= one_1; + when others => next_state <= reset; -- only on error + end case; + + when one_1 => + + case(encoded_i) is + when "0001" => next_state <= one_1; -- remain here until change + when "0100" => next_state <= one_0; + when "1000" => next_state <= two_0; + when others => next_state <= reset; -- only on error + end case; + + when two_0 => + + case(encoded_i) is + when "1000" => next_state <= two_0; -- remain here until change + when "0001" => next_state <= one_1; + when "0010" => next_state <= two_1; + when others => next_state <= reset; -- only on error + end case; + + when two_1 => + + case(encoded_i) is + when "0010" => next_state <= two_1; -- remain here until change + when "0100" => next_state <= one_0; + when "1000" => next_state <= two_0; + when others => next_state <= reset; -- only on error + end case; + + when others => + next_state <= reset; -- only on error + + end case; + end process; + + -- decoded! + process(clk_i, rst_i) + begin + if rst_i = '1' then + decoded_o <= (others => '0'); + nd_o <= '0'; + elsif rising_edge(clk_i) then + if nd_o_buff = '1' then + for i in 0 to WORD_LENGTH-1 loop + -- the bits are ror when transmitted, thus the left-most + -- bit in decoded_buffer (excluding the xmitter protocol bits) + -- describe the right-most bit in the original data word. + -- The following line of code turns 01 to 1 and 10 to 0 and it converts + -- the big endian decoded_buffer to little endian decoded_o. + if str_buffer(str_buffer'left-2*i downto str_buffer'left-1-2*i) = "01" then + decoded_o(i) <= '1'; + else + decoded_o(i) <= '0'; + end if; + end loop; + + nd_o <= '1'; + end if; + end if; + end process; + +end Behavioral; +
trunk/twoToOne/twoToOne.vhd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.