⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 a10281_ph.vhd

📁 TCM解码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
                read_counter   <= ac_t_minus_1;              ELSIF read_counter = ac_1 THEN                read_counter   <= ac_t;              ELSIF read_counter = ac_t THEN                read_counter   <= ac_2t_minus_1;              ELSIF read_counter = ac_t_plus_1 THEN                read_mem_2t    <= TRUE;                ctr_state      <= offset_ascending;                read_counter   <= ac_1;              END IF;            -- mem_2T between these two states (1 count)            WHEN offset_ascending =>              -- Count up 1..T-1, 0, T+1..2T-1, T (2T counts)              modulo_inc(read_counter);              IF read_counter = ac_t_minus_1 THEN                read_counter   <= ac_0;              ELSIF read_counter = ac_0 THEN                read_counter   <= ac_t_plus_1;              ELSIF read_counter = ac_2t_minus_1 THEN                read_counter   <= ac_t;              ELSIF read_counter = ac_t THEN                ctr_state      <= short_descending;                read_counter   <= ac_t_minus_1;              END IF;            WHEN short_descending =>              -- Count down T-1..1, 2T, 2T-1..T+1 (2T-1 counts)              modulo_dec(read_counter);              IF read_counter = ac_1 THEN                read_mem_2t    <= TRUE;                read_counter   <= ac_2t_minus_1;              ELSIF read_counter = ac_t_plus_1 THEN                read_counter <= ac_0;                ctr_state <= normal_ascending;              END IF;            WHEN OTHERS =>                ctr_state <= normal_ascending;          END CASE;            END IF; -- NOT read_mem_2t      END IF; -- enable    END IF;   -- clock  END PROCESS addrgen;    tre_d1 : PROCESS (reset_n, clk_out)  BEGIN    IF reset_n = '0' THEN      tre_rd_index  <= ( OTHERS => '0' );      tre_rd_d1     <= ( OTHERS => '0' );      rd_sel        <= '0';      rd_sel_2t     <= FALSE;      trellis_en_d1 <= '0';      shift_d       <= ( OTHERS => '0' );      shift_y       <= ( OTHERS => '0' );      mask_counter_d1  <= ( OTHERS => '0' );      reverser_shift_d1 <= FALSE;      mask_counter_d3   <= ( OTHERS => '0' );    ELSIF clk_out'EVENT AND clk_out = '1' THEN      IF viterbi_init = '1' THEN        tre_rd_index  <= ( OTHERS => '0' );        tre_rd_d1     <= ( OTHERS => '0' );        rd_sel        <= '0';        rd_sel_2t     <= FALSE;        trellis_en_d1 <= '0';        shift_d       <= ( OTHERS => '0' );        shift_y       <= ( OTHERS => '0' );        mask_counter_d1  <= ( OTHERS => '0' );        reverser_shift_d1 <= FALSE;        mask_counter_d3   <= ( OTHERS => '0' );      ELSIF clk_out_enable = '1' THEN        tre_rd_index  <= tre_rd_d1;        tre_rd_d1     <= trellis_sel;        rd_sel        <= read_counter(0);        rd_sel_2t     <= read_mem_2t;        trellis_en_d1 <= trellis_en;        shift_d(conv_integer(unsigned(tre_rd_index))) <= selected_memory_bit;        shift_y(conv_integer(unsigned(tre_rd_index))) <= selected_y;        mask_counter_d1  <= mask_counter;        reverser_shift_d1 <= reverser_shift_left;        mask_counter_d3   <= mask_counter_tre;      END IF;    END IF;  END PROCESS tre_d1;     -- this is the 2T'th memory location.  memory_element_2t : PROCESS   BEGIN    WAIT UNTIL clk_out'EVENT AND clk_out = '1';    IF clk_out_enable = '1' AND write_mem_2t THEN      mem_2t(conv_integer(unsigned(tre_rd_d1))) <= out_y & decision;    END IF;  END PROCESS memory_element_2t;    -- The traceback unit.  The "addrgen" process provides a correctly sequenced  -- data stream.  This process must synchronised to the block boundaries, and  -- perform the traceback on the data, which it must push into the bit reverser.  traceback_cont : PROCESS (reset_n, clk_out)  BEGIN    IF reset_n = '0' THEN        linear_counter  <= (OTHERS => '0');        mask_counter    <= (OTHERS => '0');        mask_counter_tre<= (OTHERS => '0');        mask_counter_d2    <= (OTHERS => '0');        capture_regs    <= TRUE;    ELSIF clk_out'EVENT AND clk_out = '1' THEN      IF viterbi_init = '1' THEN        linear_counter  <= (OTHERS => '0');        mask_counter    <= (OTHERS => '0');        mask_counter_tre<= (OTHERS => '0');        mask_counter_d2    <= (OTHERS => '0');        capture_regs    <= TRUE;      ELSIF clk_out_enable = '1' AND trellis_en = '1' THEN        mask_counter_d2    <= mask_counter;        mask_counter_tre<= mask_counter_d2;        -- Linear counter is for timing purposes within the T-clock macro cycle        -- The "write_mem_2t" term synchronises it to the address generator.        IF read_mem_2t OR linear_counter = linear_counter_max THEN          linear_counter <= (OTHERS => '0');          capture_regs   <= TRUE;          IF mask_counter /= 3 THEN            mask_counter <= mask_counter + 1;          END IF;        ELSE          linear_counter <= linear_counter + 1;          --IF linear_counter = conv_unsigned(memory_order-1, traceback_address_type'LENGTH) THEN            capture_regs <= FALSE;          --END IF;        END IF;      END IF;    END IF;  END PROCESS traceback_cont;      shift_cont : PROCESS (reset_n, clk_out)  BEGIN    IF reset_n = '0' THEN        reverser_shift_left <= FALSE;    ELSIF clk_out'EVENT AND clk_out = '1' THEN      IF viterbi_init = '1' THEN        reverser_shift_left <= FALSE;      ELSIF clk_out_enable = '1' AND trellis_en = '1' THEN        --IF linear_counter = linear_counter_max THEN        IF linear_counter = linear_counter_zero THEN          -- initialise traceback          reverser_shift_left <= NOT reverser_shift_left;        END IF;      END IF;    END IF;  END PROCESS shift_cont;       traceback : PROCESS (reset_n, clk_out)  variable tmp : unsigned(memory_order-1 DOWNTO 0);  variable gs_tmp : unsigned(memory_order-1 DOWNTO 0);  BEGIN    IF reset_n = '0' THEN        shifter         <= (OTHERS => (OTHERS => '-'));        reverser        <= (OTHERS => (OTHERS => '-'));        reverser_y      <= (OTHERS => (OTHERS => '0'));    ELSIF clk_out'EVENT AND clk_out = '1' THEN               IF clk_out_enable = '1' THEN        IF linear_counter = linear_counter_zero AND trellis_en_d1 = '1' THEN          -- initialise traceback          FOR index IN 11 DOWNTO 0 LOOP            shifter(index)  <= unsigned(regex(index)(0));          END LOOP;        ELSE          -- do a cycle of traceback          tmp := shifter(conv_integer(unsigned(tre_rd_index)));          tmp := tmp( memory_order-2 DOWNTO 0 ) & tmp( memory_order-1 );          gs_tmp := ( OTHERS => '0' );          gs_tmp( memory_order-1 ) := selected_memory_bit;          tmp := unsigned( std_logic_vector( tmp ) xor std_logic_vector( gs_tmp ));           shifter(conv_integer(unsigned(tre_rd_index)))  <= tmp;        END IF;        IF reverser_shift_d1 THEN             reverser(conv_integer(unsigned(tre_rd_index))) <= reverser(conv_integer(unsigned(tre_rd_index)))(traceback_length-2 DOWNTO 0) & shift_d(conv_integer(unsigned(tre_rd_index)));          reverser_y(conv_integer(unsigned(tre_rd_index))) <= reverser_y(conv_integer(unsigned(tre_rd_index)))(traceback_length-2 DOWNTO 0) & shift_y(conv_integer(unsigned(tre_rd_index)));        ELSE          reverser(conv_integer(unsigned(tre_rd_index))) <= shift_d(conv_integer(unsigned(tre_rd_index))) & reverser(conv_integer(unsigned(tre_rd_index)))(traceback_length-1 DOWNTO 1);          reverser_y(conv_integer(unsigned(tre_rd_index))) <= shift_y(conv_integer(unsigned(tre_rd_index))) & reverser_y(conv_integer(unsigned(tre_rd_index)))(traceback_length-1 DOWNTO 1);        END IF;                --IF reverser_shift_d1 THEN           --  reverser(conv_integer(unsigned(tre_rd_index))) <= reverser(conv_integer(unsigned(tre_rd_index)))(traceback_length-2 DOWNTO 0) & selected_memory_bit;        --  reverser_y(conv_integer(unsigned(tre_rd_index))) <= reverser_y(conv_integer(unsigned(tre_rd_index)))(traceback_length-2 DOWNTO 0) & selected_y;        --ELSE        --  reverser(conv_integer(unsigned(tre_rd_index))) <= selected_memory_bit & reverser(conv_integer(unsigned(tre_rd_index)))(traceback_length-1 DOWNTO 1);        --  reverser_y(conv_integer(unsigned(tre_rd_index))) <= selected_y & reverser_y(conv_integer(unsigned(tre_rd_index)))(traceback_length-1 DOWNTO 1);        --END IF;      END IF;    END IF;  END PROCESS traceback;    -- The register exchange unit.  This must synchronise to the block boundaries  -- as determined by the linear counter  regex_unit : PROCESS (reset_n, clk_out)    VARIABLE vec_state                  : std_logic_vector(memory_order-1 DOWNTO 0);    VARIABLE prev_state_a               : std_logic_vector(memory_order-1 DOWNTO 0);    VARIABLE prev_state_b               : std_logic_vector(memory_order-1 DOWNTO 0);    VARIABLE prev_reg_a                 : std_logic_vector(memory_order-1 DOWNTO 0);    VARIABLE prev_reg_b                 : std_logic_vector(memory_order-1 DOWNTO 0);  BEGIN    IF reset_n = '0' THEN        regex     <= (OTHERS => (OTHERS => regex_zero));    ELSIF clk_out'EVENT AND clk_out = '1' THEN      IF viterbi_init = '1' THEN        regex     <= (OTHERS => (OTHERS => regex_zero));      ELSIF clk_out_enable = '1' THEN        -- The Register Exchange unit, of length memory_order        FOR state IN 0 TO trellis_width-1 LOOP          -- get the bitwise representation of this state          vec_state := std_logic_vector(conv_unsigned(state, vec_state'LENGTH));          -- the two previous states for getting to this state          prev_state_a := vec_state(vec_state'HIGH-1 DOWNTO 0) & vec_state(vec_state'HIGH);          prev_state_b := (vec_state(vec_state'HIGH-1 DOWNTO 0) & vec_state(vec_state'HIGH)) xor gs;          -- and their respective registers          prev_reg_a   := regex(conv_integer(unsigned(tre_rd_d1)))(conv_integer(unsigned(prev_state_a)));          prev_reg_b   := regex(conv_integer(unsigned(tre_rd_d1)))(conv_integer(unsigned(prev_state_b)));          -- the above should just synthesise to wires.  Now for some logic...          IF capture_regs THEN                    IF decision(state) = '0' THEN              regex(conv_integer(unsigned(tre_rd_d1)))(state) <= prev_state_a;            ELSE              regex(conv_integer(unsigned(tre_rd_d1)))(state) <= prev_state_b;            END IF;          ELSE            IF decision(state) = '0' THEN              regex(conv_integer(unsigned(tre_rd_d1)))(state) <= prev_reg_a;            ELSE              regex(conv_integer(unsigned(tre_rd_d1)))(state) <= prev_reg_b;            END IF;          END IF;              END LOOP;      END IF; -- clk_out_enable    END IF; -- clock  END PROCESS regex_unit;  END rtl ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -