Skip to content
Snippets Groups Projects
Commit d9dde548 authored by Gautier TANDEAU DE MARSAC's avatar Gautier TANDEAU DE MARSAC
Browse files

séance 9/05

parent a0f3a451
Branches
No related tags found
No related merge requests found
......@@ -44,7 +44,6 @@ entity controlUnit is
end entity controlUnit;
architecture archi_operativeUnit of controlUnit is
type T_state is (WAIT_SAMPLE, STORE, PROCESSING_LOOP, OUTPUT, WAIT_END_SAMPLE); -- state list
signal SR_currentState : T_state;
signal SR_nextState : T_state;
......@@ -52,42 +51,60 @@ architecture archi_operativeUnit of controlUnit is
begin
-- Process to describe the state register
-- Current state is provide at the output of the register
-- and is updated with the next state at each rising edge of clock
process (_BLANK_) is
process (I_clock, I_reset) is
begin
if I_reset = '1' then -- asynchronous reset (active high)
SR_currentState <= _BLANK_
SR_currentState <= WAIT_SAMPLE;
elsif rising_edge(I_clock) then -- rising clock edge
_BLANK_
SR_currentState <= SR_nextState;
end if;
end process;
-- Combinatorial process computing the next state which depends on
-- the current state and on the inputs
process (_BLANK_) is
-- Combinatorial process computing the next state
process (SR_currentState, I_inputSampleValid, I_processingDone) is
begin
case SR_currentState is
when WAIT_SAMPLE =>
_BLANK_
if I_inputSampleValid = '1' then
SR_nextState <= STORE;
else
SR_nextState <= WAIT_SAMPLE;
end if;
when STORE =>
SR_nextState <= PROCESSING_LOOP;
when PROCESSING_LOOP =>
if I_processingDone = '1' then
SR_nextState <= OUTPUT;
else
SR_nextState <= PROCESSING_LOOP;
end if;
when OUTPUT =>
SR_nextState <= WAIT_END_SAMPLE;
when WAIT_END_SAMPLE =>
if I_inputSampleValid = '0' then
SR_nextState <= WAIT_SAMPLE;
else
SR_nextState <= WAIT_END_SAMPLE;
end if;
when others =>
SR_nextState <= WAIT_SAMPLE;
when others => null;
end case;
end process;
-- Rules to compute the outputs depending on the current state
-- (and on the inputs, if you want a Mealy machine).
O_loadShift <= '1' when _BLANK_ else '0';
O_initAddress <= '1' when _BLANK_ else '0';
O_incrAddress <= '1' when _BLANK_ else '0';
O_initSum <= '1' when _BLANK_ else '0';
O_loadSum <= '1' when _BLANK_ else '0';
O_loadOutput <= '1' when _BLANK_ else '0';
O_FilteredSampleValid <= '1' when _BLANK_ else '0';
-- Outputs based on current state
O_loadShift <= '1' when SR_currentState = STORE else '0';
O_initAddress <= '1' when SR_currentState = STORE else '0';
O_incrAddress <= '1' when SR_currentState = PROCESSING_LOOP else '0';
O_initSum <= '1' when SR_currentState = STORE else '0';
O_loadSum <= '1' when SR_currentState = PROCESSING_LOOP else '0';
O_loadOutput <= '1' when SR_currentState = OUTPUT else '0';
O_FilteredSampleValid <= '1' when SR_currentState = OUTPUT else '0';
end architecture archi_operativeUnit;
......@@ -45,7 +45,7 @@ entity operativeUnit is
I_incrAddress : in std_logic; -- Control signal to increment register read address
I_initSum : in std_logic; -- Control signal to initialize the MAC register
I_loadSum : in std_logic; -- Control signal to load the MAC register;
I_loadY : in std_logic; -- Control signal to load Y register
I_loadOutput : in std_logic; -- Control signal to load Y register
O_processingDone : out std_logic; -- Indicate that processing is done
O_filteredSample : out std_logic_vector(15 downto 0) -- filtered sample
);
......@@ -56,45 +56,17 @@ architecture arch_operativeUnit of operativeUnit is
type registerFile is array(0 to 15) of signed(15 downto 0);
signal SR_coefRegister : registerFile;
signal SR_shiftRegister : registerFile; -- shift register file used to store and shift input samples
signal SC_multOperand1 : signed(15 downto 0);
signal SC_multOperand2 : signed(15 downto 0);
signal SC_MultResult : signed(31 downto 0); -- Result of the multiplication Xi*Hi
signal SC_addResult : signed(35 downto 0); -- result of the accumulation addition
signal SR_sum : signed(35 downto 0); -- Accumulation register
signal SR_filteredSample: signed(15 downto 0); -- filtered sample storage register
signal SR_filteredSample: signed(15 downto 0); -- filtered sample storage register
signal SR_readAddress : integer range 0 to 15; -- register files read address
begin
-- Low-pass filter provided with octave (or Matlab ;)) script :
-- pkg load signal
--
-- fs=44100
-- fn=fs/2
-- n=16
-- fc=300
-- fLP=fir1(n-1,fc/fn,"low");
--
-- function quantized_signal = quantize(signal, q)
-- % Quantize the signal to q bits
-- max_val = 2^(q-1) - 1;
-- min_val = -2^(q-1);
-- quantized_signal = round(min(max(signal * 2^(q-1), min_val), max_val)) / 2^(q-1);
-- end
--
-- q=16
--
-- fLPq= quantize(fLP,q);
--
-- for i=1:n
-- printf("to_signed(%d,%d),\n", fLPq(i)*2^(q-1),q);
-- endfor
-- Table to store the filter coefficients obtained with the previous script
SR_coefRegister <= (to_signed(317,16),
to_signed(476,16),
to_signed(925,16),
......@@ -112,60 +84,74 @@ begin
to_signed(476,16),
to_signed(317,16)
);
-- Process to describe the shift register storing the input samples
shift : process (_BLANK_) is
begin -- process shift
if I_reset = '1' then -- asynchronous reset (active high)
shift : process (I_clock, I_reset) is
begin
if I_reset = '1' then
SR_shiftRegister <= (others => (others => '0'));
elsif _BLANK_
elsif rising_edge(I_clock) then
if I_loadShift = '1' then
SR_shiftRegister <= SR_shiftRegister(0 to 14) & signed(I_inputSample);
end if;
end if;
end process shift;
-- Process to describe the counter providing the selection adresses
-- of the multiplexers
incr_address : process (_BLANK_) is
incr_address : process (I_clock, I_reset) is
begin
if I_reset = '1' then -- asynchronous reset (active high)
if I_reset = '1' then
SR_readAddress <= 0;
elsif _BLANK_
elsif rising_edge(I_clock) then
if I_initAddress = '1' then
SR_readAddress <= 0;
elsif I_incrAddress = '1' then
SR_readAddress <= SR_readAddress + 1;
end if;
end if;
end process incr_address;
-- Signal detecting that the next cycle will be the one
-- providing the last product used to compute the convolution
O_processingDone <= '1' when _BLANK_;
O_processingDone <= '1' when SR_readAddress = 15 else '0';
-- Signals connected with multiplexers (SIMPLY inferred with table indices)
SC_multOperand1 <= _BLANK_; -- 16 bits
SC_multOperand2 <= _BLANK_; -- 16 bits
SC_multOperand1 <= SR_shiftRegister(SR_readAddress);
SC_multOperand2 <= SR_coefRegister(SR_readAddress);
-- Multiplication of the operands
SC_MultResult <= _BLANK_; -- 32 bits
SC_MultResult <= SC_multOperand1 * SC_multOperand2;
-- Sum of the multiplication result and the accumulated value
SC_addResult <= resize(SC_MultResult, SC_addResult'length) + SR_sum;
-- Register to store the accumulated value if the loadSum is active
-- It also reduces the width of the sum to fit to the input and output
-- signal widths (be careful with truncating/rounding)
sum_acc : process (_BLANK_) is
sum_acc : process (I_clock, I_reset) is
begin
if I_reset = '1' then -- asynchronous reset (active high)
if I_reset = '1' then
SR_sum <= (others => '0');
elsif _BLANK_
elsif rising_edge(I_clock) then
if I_initSum = '1' then
SR_sum <= (others => '0');
elsif I_loadSum = '1' then
SR_sum <= SC_addResult;
end if;
end if;
end process sum_acc;
-- Register to store the final result if the loadOuput is active
store_result : process (_BLANK_) is
-- Register to store the final result if the loadOutput is active
store_result : process (I_clock, I_reset) is
begin
_BLANK_
if I_reset = '1' then
SR_filteredSample <= (others => '0');
elsif rising_edge(I_clock) then
if I_loadOutput = '1' then
SR_filteredSample <= SR_sum(30 downto 15);
end if;
end if;
end process store_result;
O_filteredSample <= std_logic_vector(SR_filteredSample);
end architecture arch_operativeUnit;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment