📄 a10281_sm.vhd
字号:
-- Drawing number : D10281-- Drawing description : Viterbi decoder core---- Entity name : D10281_SM-- Short description : State metric calculation unit-- Architecture(s) : rtl---- Description :-- -- The state metric unit, containing an array of <trellis_width> Add-Compare--- Select (ACS) units. The ACS unit itself has been split out into a separate-- entity, to be instantiated multiple times. This greatly simplifies and-- speeds synthesis.---- Don't bother calculating the most likely path, because it makes very little-- difference to the quality of results: for poor Eb/N0 it affects only the-- 3rd most significant digit of residual BER for code rate 1/2; for good-- Eb/N0 it affects nothing !!---- This code is based on extensive simulation with a 'C' model.ARCHITECTURE rtl OF d10281_sm IS--==========================================-- Combinatorial signals--========================================== SIGNAL bmtable : branch_metric_table; SIGNAL next_sm : state_metric_array; SIGNAL next_decision : decision_vector_type; -- Wiring to the ACS unit inputs TYPE branch_metric_array IS ARRAY (0 TO trellis_width-1) OF branch_metric_type; SIGNAL bm_from_a : branch_metric_array; SIGNAL bm_from_b : branch_metric_array; SIGNAL sm_from_a : state_metric_array; SIGNAL sm_from_b : state_metric_array; SIGNAL y_from_a : std_logic_vector( trellis_width-1 DOWNTO 0 ); SIGNAL y_from_b : std_logic_vector( trellis_width-1 DOWNTO 0 ); SIGNAL next_out_y : std_logic_vector( trellis_width-1 DOWNTO 0 );--==========================================-- Registers--==========================================--OUTPUT decision : decision_vector_type; SIGNAL sm : trellis_metric_array; -- An ACS unit: COMPONENT d10281_acs PORT ( bm_from_a : IN branch_metric_type; bm_from_b : IN branch_metric_type; sm_from_a : IN state_metric_type; sm_from_b : IN state_metric_type; y_from_a : IN std_logic; y_from_b : IN std_logic; next_sm : OUT state_metric_type; out_y : OUT std_logic; decision : OUT std_logic ); END COMPONENT;BEGIN--===========================================================-- Combinatorial--=========================================================== -- Put branch metrics in a table for easy access bmtable(0) <= bm0; bmtable(1) <= bm1; bmtable(2) <= bm2; bmtable(3) <= bm3; -- work out how to wire up SM and BM inputs to the ACS units. This should -- synthesise to nothing except wires! evaluate_trellis : PROCESS ( sm, bmtable, data_y, trellis_sel ) VARIABLE vec_state : std_logic_vector(memory_order-1 DOWNTO 0); -- VARIABLE expected_in : std_logic; 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_state_a_rxsymbol : unsigned(1 DOWNTO 0); VARIABLE prev_state_b_rxsymbol : unsigned(1 DOWNTO 0); BEGIN FOR state IN state_metric_array'RANGE 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; -- These are the metrics to feed to the ACS units sm_from_a(state) <= sm(conv_integer(unsigned(trellis_sel)))(conv_integer(unsigned(prev_state_a))); sm_from_b(state) <= sm(conv_integer(unsigned(trellis_sel)))(conv_integer(unsigned(prev_state_b))); -- Expected input to get to this state is MSB of state -- expected_in := vec_state(vec_state'HIGH); -- Input symbol calc for each of prev_states to get to here prev_state_a_rxsymbol := genx(prev_state_a, '0') & geny(prev_state_a, '0'); prev_state_b_rxsymbol := genx(prev_state_b, '1') & geny(prev_state_b, '1'); -- Select the branch metric applicable to each entry to this state bm_from_a(state) <= bmtable(conv_integer(prev_state_a_rxsymbol)); bm_from_b(state) <= bmtable(conv_integer(prev_state_b_rxsymbol)); y_from_a(state) <= data_y(conv_integer(prev_state_a_rxsymbol)); y_from_b(state) <= data_y(conv_integer(prev_state_b_rxsymbol)); END LOOP; END PROCESS evaluate_trellis; -- instantiate the required number of ACS units acs_array : FOR state IN state_metric_array'RANGE GENERATE d10281_acs_n : d10281_acs PORT MAP ( bm_from_a => bm_from_a(state), bm_from_b => bm_from_b(state), sm_from_a => sm_from_a(state), sm_from_b => sm_from_b(state), y_from_a => y_from_a(state), y_from_b => y_from_b(state), next_sm => next_sm(state), out_y => next_out_y(state), decision => next_decision(state) ); END GENERATE; --===========================================================-- Clocked--=========================================================== sm_regs : PROCESS(reset_n, clk_out) BEGIN IF reset_n = '0' THEN sm <= (OTHERS => (OTHERS => (state_metric_type'RANGE => '0'))); decision <= (OTHERS => '0'); out_y <= (OTHERS => '0'); ELSIF clk_out'EVENT AND clk_out = '1' THEN IF viterbi_init = '1' THEN sm <= (OTHERS => (OTHERS => (state_metric_type'RANGE => '0'))); decision <= (OTHERS => '0'); out_y <= (OTHERS => '0'); ELSIF clk_out_enable = '1' THEN sm(conv_integer(unsigned(trellis_sel))) <= next_sm; decision <= next_decision; out_y <= next_out_y; END IF; END IF; END PROCESS sm_regs;END rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -