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

Subversion Repositories turbocodes

[/] [turbocodes/] [trunk/] [src/] [vhdl/] [trellis2_synth.vhd] - Rev 7

Compare with Previous | Blame | View Log

----------------------------------------------------------------------
----                                                              ----
----  trellis2_synth.vhd                                          ----
----                                                              ----
----  This file is part of the turbo decoder IP core project      ----
----  http://www.opencores.org/projects/turbocodes/               ----
----                                                              ----
----  Author(s):                                                  ----
----      - David Brochart(dbrochart@opencores.org)               ----
----                                                              ----
----  All additional information is available in the README.txt   ----
----  file.                                                       ----
----                                                              ----
----------------------------------------------------------------------
----                                                              ----
---- Copyright (C) 2005 Authors                                   ----
----                                                              ----
---- This source file may be used and distributed without         ----
---- restriction provided that this copyright statement is not    ----
---- removed from the file and that any derivative work contains  ----
---- the original copyright notice and the associated disclaimer. ----
----                                                              ----
---- This source file 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 source 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.                                                     ----
----                                                              ----
---- You should have received a copy of the GNU Lesser General    ----
---- Public License along with this source; if not, download it   ----
---- from http://www.opencores.org/lgpl.shtml                     ----
----                                                              ----
----------------------------------------------------------------------
 
 
 
architecture synth of trellis2 is
    signal revWeight    : ARRAY_4xTREL2_LEN;
    signal pathIdReg    : ARRAY8d;
    signal reg          : ARRAY_TREL2_LENx8;
begin
    process (clk, rst)
        variable free       : std_logic_vector(7 downto 0);
        variable freeBeg    : std_logic_vector(7 downto 0);
        variable pastState  : ARRAY8d;
        variable pathId     : ARRAY8d;
        variable freePathId : INT3BIT;
        variable op         : ARRAY4a;
        variable tmp        : ARRAY4a;
        variable revWeightTmp   : ARRAY_4xTREL2_LEN;
        variable revWeightFilt  : ARRAY3a;
        variable notZero    : ARRAY6b;
        variable minTmp     : std_logic_vector(0 to 2);
        variable ind        : ARRAY6b;
        variable tmp4       : std_logic_vector(ACC_DIST_WIDTH downto 0);
    begin
        if rst = '0' then
            for i in 0 to 3 loop
                for j in 0 to TREL2_LEN - 1 loop
                    revWeight(i * TREL2_LEN + j) <= (others => '0');
                end loop;
            end loop;
            a       <= '0';
            b       <= '0';
            llr0    <= (others => '0');
            llr1    <= (others => '0');
            llr2    <= (others => '0');
            llr3    <= (others => '0');
            for i in 0 to 7 loop
                pathIdReg(i) <= i;
                for j in 0 to TREL2_LEN - 1 loop
                    reg(j * 8 + i) <= "00";
                end loop;
            end loop;
        elsif clk = '1' and clk'event then
            free := "11111111";
            for i in 0 to 7 loop
                pastState(i) := TRANS2STATE(i * 4 + conv_integer(unsigned(selTrans(i))));
                pathId(i) := pathIdReg(pastState(i));
                free(pathId(i)) := '0';
            end loop;
            freeBeg := "11111111";
            for i in 0 to 7 loop
                if freeBeg(pathId(i)) = '1' then
                    reg(0 * 8 + pathId(i)) <= selTrans(i);
                    freeBeg(pathId(i)) := '0';
                    pathIdReg(i) <= pathId(i);
                    for j in 0 to TREL2_LEN - 2 loop
                        reg((j + 1) * 8 + pathId(i)) <= reg(j * 8 + pathId(i));
                    end loop;
                else
                    if free(0) = '1' then
                        freePathId := 0;
                    end if;
                    if free(1 downto 0) = "10" then
                        freePathId := 1;
                    end if;
                    if free(2 downto 0) = "100" then
                        freePathId := 2;
                    end if;
                    if free(3 downto 0) = "1000" then
                        freePathId := 3;
                    end if;
                    if free(4 downto 0) = "10000" then
                        freePathId := 4;
                    end if;
                    if free(5 downto 0) = "100000" then
                        freePathId := 5;
                    end if;
                    if free(6 downto 0) = "1000000" then
                        freePathId := 6;
                    end if;
                    if free(7 downto 0) = "10000000" then
                        freePathId := 7;
                    end if;
                    reg(0 * 8 + freePathId) <= selTrans(i);
                    free(freePathId) := '0';
                    pathIdReg(i) <= freePathId;
                    for j in 0 to TREL2_LEN - 2 loop
                        reg((j + 1) * 8 + freePathId) <= reg(j * 8 + pathId(i));
                    end loop;
                end if;
            end loop;
            a <= reg((TREL2_LEN - 1) * 8 + pathId(conv_integer(unsigned(selState))))(1);
            b <= reg((TREL2_LEN - 1) * 8 + pathId(conv_integer(unsigned(selState))))(0);
            for i in 0 to 3 loop
                for j in 0 to TREL2_LEN - 2 loop
                    for k in 0 to 3 loop
                        if reg(j * 8 + pathId(conv_integer(unsigned(state(k))))) = std_logic_vector(conv_unsigned(i, 2)) and state(k) /= selState then
                            op(k) := weight(k);
                        else
                            op(k) := std_logic_vector(conv_unsigned((2 ** ACC_DIST_WIDTH) - 1, ACC_DIST_WIDTH));
                        end if;
                    end loop;
                    if conv_integer(unsigned(op(0))) < conv_integer(unsigned(op(1))) then
                        tmp(0) := op(0);
                    else
                        tmp(0) := op(1);
                    end if;
                    if conv_integer(unsigned(op(2))) < conv_integer(unsigned(op(3))) then
                        tmp(1) := op(2);
                    else
                        tmp(1) := op(3);
                    end if;
                    if conv_integer(unsigned(tmp(0))) < conv_integer(unsigned(tmp(1))) then
                        tmp(2) := tmp(0);
                    else
                        tmp(2) := tmp(1);
                    end if;
                    if conv_integer(unsigned(tmp(2))) < conv_integer(unsigned(revWeight(i * TREL2_LEN + j))) then
                        revWeightTmp(i * TREL2_LEN + j + 1) := tmp(2);
                    else
                        revWeightTmp(i * TREL2_LEN + j + 1) := revWeight(i * TREL2_LEN + j);
                    end if;
                end loop;
                revWeightTmp(i * TREL2_LEN + 0) := weight(i);
            end loop;
            for j in 0 to 1 loop
                if revWeightTmp(0 * TREL2_LEN + j) =  std_logic_vector(conv_unsigned(0, ACC_DIST_WIDTH)) then
                    notZero(j * 3 + 0)  := 1;
                    notZero(j * 3 + 1)  := 2;
                    notZero(j * 3 + 2)  := 3;
                elsif revWeightTmp(1 * TREL2_LEN + j) = std_logic_vector(conv_unsigned(0, ACC_DIST_WIDTH)) then
                    notZero(j * 3 + 0)  := 0;
                    notZero(j * 3 + 1)  := 2;
                    notZero(j * 3 + 2)  := 3;
                elsif revWeightTmp(2 * TREL2_LEN + j) = std_logic_vector(conv_unsigned(0, ACC_DIST_WIDTH)) then
                    notZero(j * 3 + 0)  := 0;
                    notZero(j * 3 + 1)  := 1;
                    notZero(j * 3 + 2)  := 3;
                elsif revWeightTmp(3 * TREL2_LEN + j) = std_logic_vector(conv_unsigned(0, ACC_DIST_WIDTH)) then
                    notZero(j * 3 + 0)  := 0;
                    notZero(j * 3 + 1)  := 1;
                    notZero(j * 3 + 2)  := 2;
                end if;
                if conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 0) * TREL2_LEN + j))) <= conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 1) * TREL2_LEN + j))) then
                    minTmp(0) := '0';
                else
                    minTmp(0) := '1';
                end if;
                if conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 0) * TREL2_LEN + j))) <= conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 2) * TREL2_LEN + j))) then
                    minTmp(1) := '0';
                else
                    minTmp(1) := '1';
                end if;
                if conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 1) * TREL2_LEN + j))) <= conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 2) * TREL2_LEN + j))) then
                    minTmp(2) := '0';
                else
                    minTmp(2) := '1';
                end if;
                if minTmp = "000" then
                    ind(j * 3 + 0)  := 0;
                    ind(j * 3 + 1)  := 1;
                    ind(j * 3 + 2)  := 2;
                elsif minTmp = "001" then
                    ind(j * 3 + 0)  := 0;
                    ind(j * 3 + 1)  := 2;
                    ind(j * 3 + 2)  := 1;
                elsif minTmp = "100" then
                    ind(j * 3 + 0)  := 1;
                    ind(j * 3 + 1)  := 0;
                    ind(j * 3 + 2)  := 2;
                elsif minTmp = "011" then
                    ind(j * 3 + 0)  := 1;
                    ind(j * 3 + 1)  := 2;
                    ind(j * 3 + 2)  := 0;
                elsif minTmp = "110" then
                    ind(j * 3 + 0)  := 2;
                    ind(j * 3 + 1)  := 0;
                    ind(j * 3 + 2)  := 1;
                else    -- if minTmp = "111" then
                    ind(j * 3 + 0)  := 2;
                    ind(j * 3 + 1)  := 1;
                    ind(j * 3 + 2)  := 0;
                end if;
            end loop;
            for i in 0 to 2 loop
                tmp(3)  := revWeightTmp(notZero(0 * 3 + ind(0 * 3 + i)) * TREL2_LEN + 0);
                tmp4    := std_logic_vector(conv_unsigned(conv_integer(unsigned(revWeightTmp(notZero(1 * 3 + ind(1 * 3 + i)) * TREL2_LEN + 1))) + (2 ** (ACC_DIST_WIDTH - 4)), ACC_DIST_WIDTH + 1));
                if conv_integer(unsigned(tmp(3))) < conv_integer(unsigned(tmp4)) then
                    revWeightFilt(ind(0 * 3 + i)) := tmp(3);
                else
                    revWeightFilt(ind(0 * 3 + i)) := tmp4(ACC_DIST_WIDTH - 1 downto 0);
                end if;
            end loop;
            for i in 0 to 2 loop
                revWeightTmp(notZero(0 * 3 + i) * TREL2_LEN + 0) := revWeightFilt(i);
            end loop;
            for i in 0 to 3 loop
                for j in 0 to TREL2_LEN - 1 loop
                    revWeight(TREL2_LEN * i + j) <= revWeightTmp(TREL2_LEN * i + j);
                end loop;
            end loop;
            llr0 <= revWeight(1 * TREL2_LEN - 1);
            llr1 <= revWeight(2 * TREL2_LEN - 1);
            llr2 <= revWeight(3 * TREL2_LEN - 1);
            llr3 <= revWeight(4 * TREL2_LEN - 1);
        end if;
    end process;
end;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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