1、天津大学通信系统集成电路课程设计实验报告三基于IP核的交织器设计一、实验目的1、熟悉使用FPGA内部的IP核进行设计的基本流程。2、使用块RAM实现无线通信中的分组交织器。二、实验环境1、Quartus II 9.1 (32-Bit)2、ModelSim-Altera 6.5a (Quartus II 9.1)3、Win2000操作系统三、实验要求1、实现分组交织器2、交织器的大小为 1024,深度为 32 (32x32)3、数据宽度为 10比特4、编写测试向量证明结果的正确5、使用双口 RAM调用IP核实现四、实验内容1、IP核的基本概念 IP核(Intellectual Property
2、core),即知识产权核,是一段具有特定电路功能的硬件描述语言程序,是己验证的、可重利用的、具有某种确定功能的集成电路模块。其基本分类包括:(1)软核:可综合的源代码。用VHDL等硬件描述语言描述的功能块,不涉及用什么具体的电路实现这些功能。主要优点是设计灵活,但缺乏对时序、面积和功耗的预见性。(2)硬核:经过完全布局布线的设计。具有可预见性,但缺乏灵活性且可移植性差。(3)固核:源代码不可见,但布局布线灵活。基于 Quartus II 的 IP 核重用的基本流程(以IP核双口RAM的使用为例):2、分组交织器在数字通信中,为了提高数字信息的可靠性,通常要对传输的数字信息进行纠错编码,但信道编
3、码仅在检测和校正单个差错和不太长的差错串时才有效。然而实际信道中产生的错误往往是突发错误或突发错误与随机错误并存,这就很有可能超出纠错码的纠错能力。为了解决这一问题,常在信道编码中引入交织模块。交织器的主要作用是将原始数据序列打乱,使得交织前后数据序列的相关性减弱,即将一条消息中的相继比特以非相继方式被发送。这样,在传输过程中即使发生了成串差错,恢复成一条相继比特串的消息时,差错也就变成单个(或长度很短),这时再用信道编码纠错功能纠正差错,恢复原消息。如此可见交织技术进一步提高了系统的抗干扰性能交织编码根据交织方式的不同,可分为分组交织、卷积交织等。其中分组交织编码是一种比较常见的形式。一个典
4、型的分组交织器是一个按着NM矩阵描述的周期为TNM的交织器,这些交织器典型的特征就是在数据的读写过程中是按着行读列出或列读行出的形式进行的。交织编码引入的延时应尽可能小。本次设计实验中,为了同时满足块内交织进行32*32矩阵转置变换和延时尽可能小的要求,该交织器利用2片双口RAM实现,记作RAM1和RAM2。交织处理时,按地址从01023将输入数据全部写入RAM1,待数据全部送入RAM1后,控制信号使RAM1由写状态转换到读状态,同时,将输入的待交织数据写入RAM2,RAM2为写状态,交织器由RAM1输出数据。经过1024个时钟周期后,从RAM1读出数据的同时,RAM2写入数据。此时,改变RA
5、M1和RAM2的读写状态,RAM1开始写,从RAM2读取数据。如此反复完成数据的实时连续交织处理。五、实验步骤及结果1、IP核双口RAM的使用(1)添加IP核:点击【Tools】【MegaWizard Plug-In Manager】,在弹出的对话框中,选择【Create a new custom megafunction variation】,并点击【Next】 (2)选择IP核:选择【Memory Compiler】中的【RAM: 2-PORT】,并在【What name do you want for the output file?】中为生成的IP核模块命名。(3)配置IP参数:根据向
6、导进行配置。(4)点击finish,设计完成。2、分组交织器的设计jiaozhiqi工程由四个模块构成。他们分别是:计数器模块counter、两个RAM1024_10构成的RAM模块、存储读取地址的rom_64_6模块以及顶层的控制模块jiaozhi模块。其中RAM1024_10模块按要求采用了IP核,并采用了大小为1024*10的双端口RAM;而工程中还包含测试向量文件tb_jiaozhi.vhd。编译成功后,Modelsim仿真得到:由上图可以看出,交织器输出对输入存在延时。将图像局部放大:可以看出可在第1028个时钟信号时,交织器输出交织后的第一个数0,接着输出32,64,表明第一帧交织
7、正常,且交织存在3个时钟信号的延迟。由上图可知,输出为1023时,下一个输出是0,表明第一帧交织完成,第二帧开始交织。因此,帧的连续交织正常。仿真的输入和输出数据如下:打开datain:其中连续输入三次01023。打开dataout:交织器先是输出一连串0,然后输出32,64在实验中需要注意的地方:(1)关于写入地址的得到方法:高/低地址:000000000100010000110010000000A0A1A2A3A400001B0B1B2B3B400010C0C1C2C3C400011D0D1D2D3D432*32的RAM地址为10位,分为高5位和低5位。只要把高地位地址互换就能得到写入的地
8、址。(2)仿真输入的datain数据要足够多,设置的仿真时间要足够长。在实验中,输入的文本中有1024*3个数,由于设计的交织器是32*32的,一次可以处理1024个数,因此恰好能处理3次,由此检查交织器是否能够连续工作。设置足够长的仿真时间,是因为交织延时的存在,防止时间不够而无法正常输出。如下图:由于仿真时间设置过短以及交织延时的存在,只有1023个数据输入,且不能正确输出。六、实验感想通过这次实验,我学到了很多东西:首先,对IP核有了一定的了解,并学会了使用IP核构建双口RAM;其次,加深了对分组交织器的理解,通过自己动手实验并观察结果,对交织延时的概念更加清晰。再者,在这次实验的过程中
9、,也更为熟练的掌握了Quartus II与Modelsim联合仿真的步骤,学习了在一个工程中调用自己编写的文件的方法。附录1、交织器源文件(1)counterlibrary IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;entity counter isPort( reset : in std_logic; clock : in std_logic; cnt_wr_address : out std_logic_vector(9 downto 0); c
10、out: out std_logic; cout2: out std_logic);end counter;architecture Behavioral of counter issignal inner_reg : std_logic_vector(9 downto 0):=0000000000;signal inner_cout: std_logic :=0; begin cnt_wr_address =inner_reg; cout=inner_cout; process(clock,reset)begin if (reset = 1) then inner_reg = 0000000
11、000; elsif(clockevent and clock=1) then inner_reg = inner_reg+0000000001; if(inner_reg=1111111111)then inner_cout=NOT inner_cout; end if; if(inner_reg=0000000010)then cout2=inner_cout; end if; end if;end process;end Behavioral;(2)rom_64_6LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_UN
12、SIGNED.ALL;ENTITY rom_64_6 isPORT( rom_din : IN STD_LOGIC_VECTOR(9 DOWNTO 0); clk: IN STD_LOGIC; rom_dout_wr: OUT STD_LOGIC_VECTOR(9 DOWNTO 0); rom_dout_rd: out std_logic_vector(9 downto 0);END rom_64_6;ARCHITECTURE rtl OF rom_64_6 ISBEGIN PROCESS(clk)BEGIN IF clkEVENT AND clk=1 THEN rom_dout_rd=rom
13、_din(4 downto 0) & rom_din(9 downto 5); rom_dout_wrclk, reset=clr, cnt_wr_address=romin_address, cout=sel, cout2=sel2 );rom:ROM_64_6PORT MAP(clk=clk, rom_din=romin_address, rom_dout_rd=rd_address, rom_dout_wr=wr_address);ram1:RAM1024_10PORT MAP(clock=clk, q=dout_tmp1, data=din, wren=wren_ctl, rdaddr
14、ess=rd_address, wraddress=wr_address);ram2:RAM1024_10PORT MAP(clock=clk, q=dout_tmp2, data=din, wren=wren_ctl_2, rdaddress=rd_address, wraddress=wr_address);wren_ctl_2=not wren_ctl;PROCESS(clk) BEGIN IF clkevent and clk=1 THEN IF sel=1 THEN wren_ctl=1; - ram1 write ELSE wren_ctl=0; -ram2 write END I
15、F; if sel2=1 then dout=dout_tmp2; - ram2 read else doutclk, clr=clr, din=din, dout=dout ); Clk_process :process begin clk = 0; wait for Clk_period/2; clk = 1; wait for Clk_period/2; end process; writing: process(clk) variable line_out : line; variable line_in : line; variable input_tmp : integer; begin if(clkevent and clk=1)then readline(file_in,line_in); read(line_in,input_tmp); din=conv_std_logic_vector(input_tmp,8); write(line_out,conv_integer(dout); writeline(file_out,line_out); end if; end process;end behave;