串并转换与数据映射——FPGA子模块整理
刚写完2w字报告,写点verilog压压惊。
造轮子是件好玩儿的事。
不务正业,游手好闲……
1.串并转换模块(1 to 8)
1 `timescale 1ns / 1ps 2 ////////////////////////////////////////////////////////////////////////////////// 3 // Company: 4 // Engineer: 5 // 6 // Create Date: 20:30:15 04/14/2015 7 // Design Name: 8 // Module Name: SerialToParallel 9 // Project Name: 10 // Target Devices: 11 // Tool versions: 12 // Description: 13 // 14 // Dependencies: 15 // 16 // Revision: 17 // Revision 0.01 - File Created 18 // Additional Comments: 19 // 20 ////////////////////////////////////////////////////////////////////////////////// 21 module SerialToParallel( 22 input CLK, //时钟 23 input RSTn, //复位 24 input Enable, //输入有效 25 input DataIn, //串行输入 26 output reg Ready, //输出有效 27 output[7:0] Index, //并行数据索引 28 output[7:0] ParallelData //并行数据输出 29 ); 30 31 reg[7:0] Data_Temp; //数据缓存 32 reg[3:0] counter; //位数计数器 33 reg[3:0] state; //状态机 34 reg[7:0] Index_Temp; //索引缓存 35 36 assign Index=Index_Temp; 37 assign ParallelData=Ready?Data_Temp:8'd0; 38 39 //////////////////////////////////////// 40 //state: 41 //4'd0:复位 42 // 43 //4'd1:未复位,未使能 44 // 45 //4'd2:未复位,输入使能 46 // 47 48 always@(posedge CLK or negedge RSTn) 49 if(!RSTn) 50 begin 51 state<=4'd0; //复位 52 Ready<=0; 53 counter<=4'd0; 54 Data_Temp<=8'd0; 55 Index_Temp<=8'd0; 56 end 57 else 58 begin 59 case(state) 60 4'd0: 61 begin 62 if(!Enable)state<=4'd1; 63 else state<=4'd2; 64 Ready<=0; 65 end 66 4'd1: 67 begin 68 if(!Enable)state<=4'd1; 69 else state<=4'd2; 70 Ready<=0; 71 counter<=4'd0; 72 Data_Temp<=8'd0; 73 end 74 4'd2: 75 begin 76 if(!Enable)state<=4'd1; 77 else state<=4'd2; 78 case(counter) 79 4'd0:begin Data_Temp[0]<=DataIn;counter<=counter + 1'b1;Ready<=0;end 80 4'd1:begin Data_Temp[1]<=DataIn;counter<=counter + 1'b1;Ready<=0;end 81 4'd2:begin Data_Temp[2]<=DataIn;counter<=counter + 1'b1;Ready<=0;end 82 4'd3:begin Data_Temp[3]<=DataIn;counter<=counter + 1'b1;Ready<=0;end 83 4'd4:begin Data_Temp[4]<=DataIn;counter<=counter + 1'b1;Ready<=0;end 84 4'd5:begin Data_Temp[5]<=DataIn;counter<=counter + 1'b1;Ready<=0;end 85 4'd6:begin Data_Temp[6]<=DataIn;counter<=counter + 1'b1;Ready<=0;end 86 4'd7:begin Data_Temp[7]<=DataIn;counter<=4'd0;Index_Temp<=Index_Temp + 1'b1;Ready<=1'b1;end 87 endcase 88 end 89 endcase 90 end 91 92 endmodule
2.串并转换测试文件
1 `timescale 1ns / 1ps 2 3 //////////////////////////////////////////////////////////////////////////////// 4 // Company: 5 // Engineer: 6 // 7 // Create Date: 22:02:53 04/14/2015 8 // Design Name: SerialToParallel 9 // Module Name: C:/Users/Administrator/Documents/Tencent Files/1577197070/FileRecv/SerialToParallel/TB_SerialToParallel.v 10 // Project Name: SerialToParallel 11 // Target Device: 12 // Tool versions: 13 // Description: 14 // 15 // Verilog Test Fixture created by ISE for module: SerialToParallel 16 // 17 // Dependencies: 18 // 19 // Revision: 20 // Revision 0.01 - File Created 21 // Additional Comments: 22 // 23 //////////////////////////////////////////////////////////////////////////////// 24 25 module TB_SerialToParallel; 26 27 // Inputs 28 reg CLK; 29 reg RSTn; 30 reg Enable; 31 32 // Outputs 33 wire Ready; 34 wire [7:0] Index; 35 wire [7:0] ParallelData; 36 37 // Instantiate the Unit Under Test (UUT) 38 SerialToParallel uut ( 39 .CLK(CLK), 40 .RSTn(RSTn), 41 .Enable(Enable), 42 .DataIn(data), 43 .Ready(Ready), 44 .Index(Index), 45 .ParallelData(ParallelData) 46 ); 47 48 initial begin 49 // Initialize Inputs 50 CLK = 0; 51 RSTn = 0; 52 Enable = 0; 53 54 // Wait 100 ns for global reset to finish 55 #100;RSTn = 1;Enable = 1; 56 57 // Add stimulus here 58 forever #5 CLK = ~CLK; 59 end 60 61 wire data; 62 data_generator unit1( 63 .clock(CLK), 64 .reset(RSTn), 65 .data(data) 66 ); 67 68 69 endmodule
3.随机信号发生器(内含两个版本)
1 `timescale 1ns / 1ps 2 ////////////////////////////////////////////////////////////////////////////////// 3 // Company: 4 // Engineer: 5 // 6 // Create Date: 22:22:03 04/14/2015 7 // Design Name: 8 // Module Name: data_generator 9 // Project Name: 10 // Target Devices: 11 // Tool versions: 12 // Description: 13 // 14 // Dependencies: 15 // 16 // Revision: 17 // Revision 0.01 - File Created 18 // Additional Comments: 19 // 20 ////////////////////////////////////////////////////////////////////////////////// 21 module data_generator( 22 23 // Inputs 24 input clock, 25 input reset, 26 27 // Outputs 28 output data 29 ); 30 31 reg data_temp; 32 33 assign data = data_temp; 34 35 always@(posedge clock or negedge reset) 36 if(!reset) 37 data_temp<=1'b0; 38 else 39 data_temp<={$random} % 2; 40 41 endmodule 42 ////////////////////////////////////////////////////////////////////////////////// 43 //module data_generator( 44 // 45 // // Inputs 46 // input clock, 47 // input reset, 48 // 49 // // Outputs 50 // output[7:0] data 51 // ); 52 // 53 // reg[7:0] data_temp; 54 // 55 // assign data = data_temp; 56 // 57 // always@(posedge clock or negedge reset) 58 // if(!reset) 59 // data_temp<=8'd0; 60 // else 61 // data_temp<={$random} % 256; 62 // 63 //endmodule
4.测试图
从图中可以清晰看到,模块每采集8个串行数据执行一次输出,同时输出有效置1。
5.应用
以数字调制中的16QAM为例
输入的信息每四位进行一次编码,实轴和虚轴分别代表调制后的同相分量与正交分量,除以1/sqrt(10)进行归一化,再用8位定点数表示。
这样信息就被分成IM和RE两路。
测试图:
串并转换模块的Index[7:0]、Ready、ParallelData同步
数据映射模块的IndexOut[7:0]、QAM_Ready、RE_TEMP、IM_TEMP同步,且比串并转换模块晚一个时钟。
首先要每四位做一次串并转换,对原模板进行修改
1 `timescale 1ns / 1ps 2 ////////////////////////////////////////////////////////////////////////////////// 3 // Company: 4 // Engineer: 5 // 6 // Create Date: 20:30:15 04/14/2015 7 // Design Name: 8 // Module Name: SerialToParallel 9 // Project Name: 10 // Target Devices: 11 // Tool versions: 12 // Description: 13 // 14 // Dependencies: 15 // 16 // Revision: 17 // Revision 0.01 - File Created 18 // Additional Comments: 19 // 20 ////////////////////////////////////////////////////////////////////////////////// 21 module SerialToParallel( 22 input CLK, 23 input RSTn, 24 input Enable, 25 input DataIn, 26 output reg Ready, 27 output[7:0] Index, 28 output[3:0] ParallelData 29 ); 30 31 reg[3:0] Data_Temp; 32 reg[3:0] counter; 33 reg[3:0] state; 34 reg[7:0] Index_Temp; 35 36 assign Index=Index_Temp; 37 assign ParallelData=Ready?Data_Temp:4'd0; 38 39 //////////////////////////////////////// 40 //state: 41 //4'd0:复位 42 // 转换计数清零,输出计数清零,输出数据清零 43 //4'd1:未复位,未使能 44 // 转换计数清零,输出数据清零 45 //4'd2:未复位,输入使能 46 // 47 48 always@(posedge CLK or negedge RSTn) 49 if(!RSTn) 50 begin 51 state<=4'd0; //复位 52 Ready<=0; 53 counter<=4'd0; 54 Data_Temp<=4'd0; 55 Index_Temp<=8'd0; 56 end 57 else 58 begin 59 case(state) 60 4'd0: 61 begin 62 if(!Enable)state<=4'd1; 63 else state<=4'd2; 64 Ready<=0; 65 end 66 4'd1: 67 begin 68 if(!Enable)state<=4'd1; 69 else state<=4'd2; 70 Ready<=0; 71 counter<=4'd0; 72 Data_Temp<=4'd0; 73 end 74 4'd2: 75 begin 76 if(!Enable)state<=4'd1; 77 else state<=4'd2; 78 case(counter) 79 4'd0:begin Data_Temp[0]<=DataIn;counter<=counter + 1'b1;Ready<=0;end 80 4'd1:begin Data_Temp[1]<=DataIn;counter<=counter + 1'b1;Ready<=0;end 81 4'd2:begin Data_Temp[2]<=DataIn;counter<=counter + 1'b1;Ready<=0;end 82 4'd3:begin Data_Temp[3]<=DataIn;counter<=4'd0;Index_Temp<=Index_Temp + 1'b1;Ready<=1'b1;end 83 endcase 84 end 85 endcase 86 end 87 88 endmodule
然后进行映射:
1 `timescale 1ns / 1ps 2 ////////////////////////////////////////////////////////////////////////////////// 3 // Company: 4 // Engineer: 5 // 6 // Create Date: 22:54:28 04/14/2015 7 // Design Name: 8 // Module Name: dataout 9 // Project Name: 10 // Target Devices: 11 // Tool versions: 12 // Description: 13 // 14 // Dependencies: 15 // 16 // Revision: 17 // Revision 0.01 - File Created 18 // Additional Comments: 19 // 20 ////////////////////////////////////////////////////////////////////////////////// 21 module QAM16( 22 23 // Inputs 24 input CLK, 25 input RSTn, 26 input Enable, //输入数据有效 27 input [3:0] Data, //输入数据 28 input [7:0] Index, //输入数据索引 29 30 // Outputs 31 output reg QAM_Ready, //输出数据有效 32 output reg [7:0] RE_TEMP, //输出数据实部 33 output reg [7:0] IM_TEMP, //输出数据虚部 34 output reg [7:0] IndexOut //输出数据索引 35 ); 36 37 always@(posedge CLK or negedge RSTn) 38 if(!RSTn) 39 begin 40 RE_TEMP<=8'd0; 41 IM_TEMP<=8'd0; 42 QAM_Ready<=0; 43 IndexOut<=8'd0; 44 end 45 else 46 begin 47 if(Enable) 48 begin //数据映射 49 case(Data[1:0]) 50 2'b00:RE_TEMP[7:0]<=8'b11000011; 51 2'b10:RE_TEMP[7:0]<=8'b11101100; 52 2'b01:RE_TEMP[7:0]<=8'b00111101; 53 2'b11:RE_TEMP[7:0]<=8'b00010100; 54 endcase 55 case(Data[3:2]) 56 2'b00:IM_TEMP[7:0]<=8'b11000011; 57 2'b10:IM_TEMP[7:0]<=8'b11101100; 58 2'b01:IM_TEMP[7:0]<=8'b00111101; 59 2'b11:IM_TEMP[7:0]<=8'b00010100; 60 endcase 61 IndexOut<=Index; 62 QAM_Ready<=1; 63 end 64 else 65 begin 66 RE_TEMP<=8'd0; 67 IM_TEMP<=8'd0; 68 QAM_Ready<=0; 69 end 70 end 71 72 endmodule
测试
1 `timescale 1ns / 1ps 2 3 //////////////////////////////////////////////////////////////////////////////// 4 // Company: 5 // Engineer: 6 // 7 // Create Date: 22:02:53 04/14/2015 8 // Design Name: SerialToParallel 9 // Module Name: C:/Users/Administrator/Documents/Tencent Files/1577197070/FileRecv/SerialToParallel/TB_SerialToParallel.v 10 // Project Name: SerialToParallel 11 // Target Device: 12 // Tool versions: 13 // Description: 14 // 15 // Verilog Test Fixture created by ISE for module: SerialToParallel 16 // 17 // Dependencies: 18 // 19 // Revision: 20 // Revision 0.01 - File Created 21 // Additional Comments: 22 // 23 //////////////////////////////////////////////////////////////////////////////// 24 25 module TB_16QAM; 26 27 // Inputs 28 reg CLK; 29 reg RSTn; 30 reg Enable; 31 32 // Outputs 33 wire data; 34 wire Ready; 35 wire QAM_Ready; 36 wire [7:0] Index; 37 wire [3:0] ParallelData; 38 wire [7:0] RE_TEMP; 39 wire [7:0] IM_TEMP; 40 wire [7:0] IndexOut; 41 42 // Instantiate the Unit Under Test (UUT) 43 data_generator uut1( 44 .clock(CLK), 45 .reset(RSTn), 46 .data(data) 47 ); 48 49 SerialToParallel uut2 ( 50 .CLK(CLK), 51 .RSTn(RSTn), 52 .Enable(Enable), 53 .DataIn(data), 54 .Ready(Ready), 55 .Index(Index), 56 .ParallelData(ParallelData) 57 ); 58 QAM16 uut3 ( 59 .CLK(CLK), 60 .RSTn(RSTn), 61 .Enable(Ready), 62 .Data(ParallelData), 63 .Index(Index), 64 .RE_TEMP(RE_TEMP), 65 .IM_TEMP(IM_TEMP), 66 .IndexOut(IndexOut), 67 .QAM_Ready(QAM_Ready) 68 ); 69 70 initial begin 71 // Initialize Inputs 72 CLK = 0; 73 RSTn = 0; 74 Enable = 0; 75 76 // Wait 100 ns for global reset to finish 77 #100;RSTn = 1;Enable = 1; 78 79 // Add stimulus here 80 forever #5 CLK = ~CLK; 81 end 82 83 endmodule