📄 add_cyclic_prefix.vhd
字号:
-- added valid and ready test. now cnt is not free running when input is not valid
elsif (in_valid_r = '1') and (in_ready_r = '1') then
mem_wren <= '1';
else
mem_wren <= '0';
end if;
end if;
end process;
-- when a Buffer has been filled up, toggling appropriate signal
-- to flag this. These signals are used by the read side of FIFO
-- to determine when the Buffers contain valid data
process (clk_in, rst_in_n)
begin
if (rst_in_n = '0') then
bufa_wr_tog <= '0';
bufb_wr_tog <= '0';
elsif rising_edge(clk_in) then
if (in_eop_r2 = '1') then
if (buf_b_a_n = '0') then
--actual value of buf_b_a_n is 1 (it gets inverted after sop)
bufb_wr_tog <= not(bufb_wr_tog);
else
bufa_wr_tog <= not(bufa_wr_tog);
end if;
end if;
end if;
end process;
bufa_taken <= (bufa_wr_early_tog xor bufa_rd_tog_r2);
bufb_taken <= (bufb_wr_early_tog xor bufb_rd_tog_r2);
-- This submodule can only accept the next block of N samples from IFFT core
-- if either Buffer A OR B is empty. Due to the streaming nature of FFT
-- output, in_ready_tmp aligns with fft source eop, i.e. it de-asserts the
-- cycle after in_eop if both buffers are taken.
process (clk_in, rst_in_n)
begin -- process
if (rst_in_n = '0') then
in_ready_tmp <= '0';
in_ready_r <= '0';
elsif rising_edge(clk_in) then
if (bufa_taken = '1' and bufb_taken = '1') then
if (in_eop = '1') then
in_ready_tmp <= '0';
else
in_ready_tmp <= in_ready_tmp;
end if;
else
in_ready_tmp <= '1';
end if;
in_ready_r <= in_ready_tmp;
end if;
end process;
in_ready <= in_ready_tmp;
-- Synchronising Buffer read signals generated using clk_out into clk_in domain
process (clk_in, rst_in_n)
begin
if (rst_in_n = '0') then
bufa_rd_tog_r <= '0';
bufa_rd_tog_r2 <= '0';
bufb_rd_tog_r <= '0';
bufb_rd_tog_r2 <= '0';
elsif rising_edge(clk_in) then
bufa_rd_tog_r <= bufa_rd_tog;
bufa_rd_tog_r2 <= bufa_rd_tog_r;
bufb_rd_tog_r <= bufb_rd_tog;
bufb_rd_tog_r2 <= bufb_rd_tog_r;
end if;
end process;
-----------------------------------------------------------------------------
-- Reading Data from Dual Port RAM
-- The memory contains 2*Nmax locations (1 IFFT worth of data).
-- Reading starts at address current N - Cyclic Prefix Delay to N-1,
-- then from address 0 to current N-1,
-- then from address 2*Nmax - (current CP) to Nmax-1+current CP
-- then from address Nmax to Nmax-1+current CP and so on...,
-----------------------------------------------------------------------------
-- Determining start address for first sample for cyclic prefix for buffer A and buffer B
process (clk_out, rst_out_n)
begin
if (rst_out_n = '0') then
cp_start_addra <= (others => '0');
cp_start_addrb <= (others => '0');
elsif rising_edge(clk_out) then
if (La = 0) then
cp_start_addra <= (others => '0');
else
cp_start_addra <= std_logic_vector(to_unsigned(Na - La, MADDR_WIDTH));
end if;
if Lb = 0 then
cp_start_addrb <= std_logic_vector(to_unsigned(MDEPTH/2, MADDR_WIDTH));
else
cp_start_addrb <= std_logic_vector(to_unsigned(MDEPTH/2+Nb - Lb, MADDR_WIDTH));
end if;
end if;
end process;
-- synchronising Buffer write signals to clk_out domain
process (clk_out, rst_out_n)
begin
if (rst_out_n = '0') then
bufa_wr_tog_r <= '0';
bufa_wr_tog_r2 <= '0';
bufb_wr_tog_r <= '0';
bufb_wr_tog_r2 <= '0';
elsif rising_edge(clk_out) then
bufa_wr_tog_r <= bufa_wr_tog;
bufa_wr_tog_r2 <= bufa_wr_tog_r;
bufb_wr_tog_r <= bufb_wr_tog;
bufb_wr_tog_r2 <= bufb_wr_tog_r;
end if;
end process;
bufa_full <= bufa_wr_tog_r2 xor bufa_rd_tog;
bufb_full <= bufb_wr_tog_r2 xor bufb_rd_tog;
-- incrementing read address
process (clk_out, rst_out_n)
begin
if (rst_out_n = '0') then
mem_rdaddr <= (others => '0');
start_read <= '0';
post_cp <= '0';
bufa_rd_tog <= '0';
bufb_rd_tog <= '0';
bufa_sym_strt <= (others => '0');
bufb_sym_strt <= (others => '0');
out_eop_a <= '0';
out_eop_b <= '0';
out_valid_sr <= (others => '0');
out_eop_sr <= (others => '0');
elsif rising_edge(clk_out) then
--shift registers to delay generation of symbol start output pulse
--according to delay of reading from memory
bufa_sym_strt(1 downto 0) <= bufa_sym_strt(2 downto 1);
bufb_sym_strt(1 downto 0) <= bufb_sym_strt(2 downto 1);
bufa_sym_strt(2) <= '0';
bufb_sym_strt(2) <= '0';
--shift register to delay generation of out_valid according
--to delay of reading from memory
out_valid_sr(2 downto 0) <= out_valid_sr(3 downto 1);
out_eop_sr(0) <= out_eop_sr(1);
out_eop_sr(1) <= tmp_eop;
if (out_ready = '1') then
if ((start_read = '0') and (bufa_full = '0')) then
mem_rdaddr <= cp_start_addra;
bufa_sym_strt(2 downto 0) <= "100";
out_valid_sr(3 downto 0) <= "1000";
else
-- first time come here due to bufa_full = '0'; after the first
-- package come here due to start_read = '1'
start_read <= '1';
out_valid_sr(3) <= '1'; -- unless buffer is not available
-- to send data from
-- (overwritten later on)
if (mem_rdaddr = std_logic_vector(to_unsigned(Na-1, MADDR_WIDTH))) then
-- end of Buffer A (determine if just finished outputting cyclic prefix or
-- end of symbol)
if (post_cp = '0') then
mem_rdaddr <= std_logic_vector(to_unsigned(0, MADDR_WIDTH));
post_cp <= '1';
else
-- reading out post cp data
out_eop_a <= '1';
if (bufb_full = '1') then
mem_rdaddr <= cp_start_addrb;
post_cp <= '0';
bufa_rd_tog <= not(bufa_rd_tog);
bufb_sym_strt(2) <= '1';
else
-- buffer B is not full
out_valid_sr(3) <= '0';
end if;
end if; -- if (post_cp = '0') then
elsif (mem_rdaddr = std_logic_vector(to_unsigned(MDEPTH/2 + Nb -1, MADDR_WIDTH))) then
--end of Buffer B (determine if just finished outputting cyclic prefix or
-- end of symbol)
if (post_cp = '0') then
mem_rdaddr <= std_logic_vector(to_unsigned(MDEPTH/2, MADDR_WIDTH));
post_cp <= '1';
else
out_eop_b <= '1';
if (bufa_full = '1') then
mem_rdaddr <= cp_start_addra;
post_cp <= '0';
bufb_rd_tog <= not(bufb_rd_tog);
bufa_sym_strt(2) <= '1';
else
-- buffer A is not full
out_valid_sr(3) <= '0';
end if; -- if (bufa_full = '0')
end if; -- if (post_cp = '0') then
else
-- output cp;mem_raddr != N-1 nor 2N-1
-- may or may not in output mode
mem_rdaddr <= mem_rdaddr + 1;
out_eop_a <= '0';
out_eop_b <= '0';
end if;
end if; -- if ((start_read = '0') and (bufa_full = '0')) then
else
-- AST Sink not ready to take output: deassert out_valid
out_valid_sr(3) <= '0';
end if; -- if (out_ready = '1') then
end if; -- if (rst_out_n ='0') then
end process;
-----------------------------------------------------------------------------
-- Output AST Data Source Interface
--
--
-- This Source assumes ready_latency = 4 clk cycles.
-- Supports back pressure (i.e. allows Sink to deassert out_ready).
-- Also if no data to send, will deassert out_valid.
--
-- Upon reset waits for slave sink to assert out_ready. This is fed back to input
-- interface as when to assert slave_sink_dav.
--
-- The start of each OFDM symbol is denoted by a high on out_sop.
-----------------------------------------------------------------------------
process (clk_out, rst_out_n)
begin
if (rst_out_n = '0') then
out_real <= (others => '0');
out_imag <= (others => '0');
elsif rising_edge(clk_out) then
out_real <= mem_dout(DOUTWIDTH - 1 downto 0);
out_imag <= mem_dout(2 * DOUTWIDTH - 1 downto DOUTWIDTH);
end if;
end process;
-- out_sop pulses high at beginning of each OFDM symbol (i.e.
-- coincident with first Cyclic Prefix sample).
-- The delay is calculated from delay of reading first sample of OFDM symbol data
-- from memory upon and also includes the extra registering
-- stage above before data is clocked out of this module.
process (clk_out, rst_out_n)
begin
if (rst_out_n = '0') then
out_sop <= '0';
elsif rising_edge(clk_out) then
if (bufa_sym_strt(0) = '1') then
out_sop <= '1';
elsif (bufb_sym_strt(0) = '1') then
out_sop <= '1';
else
out_sop <= '0';
end if;
end if;
end process;
out_valid <= out_valid_sr(0);
tmp_eop <= ((out_valid_sr(2) and out_eop_a) or (out_valid_sr(2) and out_eop_b));
out_eop <= out_eop_sr(0);
output_N_L : process (clk_out, rst_out_n)
begin
if (rst_out_n = '0') then
Nout <= (others => '0');
Lout <= (others => '0');
elsif rising_edge(clk_out) then
-- Nout and Lout is sampled at output sop
if (bufa_sym_strt(0) = '1') then
Nout <= std_logic_vector(to_unsigned(Na, NWIDTH));
Lout <= std_logic_vector(to_unsigned(La, CPWIDTH));
elsif (bufb_sym_strt(0) = '1') then
Nout <= std_logic_vector(to_unsigned(Nb, NWIDTH));
Lout <= std_logic_vector(to_unsigned(Lb, CPWIDTH));
end if;
end if;
end process;
-- -----------------------------------------------------------------------------
-- -- test simulation results; not synthesizable. Comment out this section when
-- -- running synthesis. Uncomment this section if want to use the MATLAB
-- -- script to check CP insertion results.
-- -----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
-- Write Real and Imginary Components of IFFT Output to Files
-- ---------------------------------------------------------------------------------------------
-- testbench_o : process(clk_in, rst_in_n) is
-- file ro_file : text open write_mode is "fft_real_output_vhd.txt";
-- variable rdata : line;
-- variable data_r : integer;
-- file io_file : text open write_mode is "fft_imag_output_vhd.txt";
-- variable idata : line;
-- variable data_i : integer;
-- begin
-- if rising_edge(clk_in) and rst_in_n = '1' then
-- if(in_valid_r = '1' and in_ready_r = '1') then
---- data_r := to_integer(signed(d_real));
---- data_i := to_integer(signed(d_imag));
-- data_r := to_integer(signed(in_real_r));
-- data_i := to_integer(signed(in_imag_r));
-- write(rdata, data_r);
-- writeline(ro_file, rdata);
-- write(idata, data_i);
-- writeline(io_file, idata);
-- end if;
-- end if;
-- end process testbench_o;
-----------------------------------------------------------------------------
end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -