主要测试一下FPGA芯片的IO经过了核心板,底板,底板接口,最后到扩展板,整个对应是否正确。
以为有70多个IO,也测试每一个,要想一个办法能简洁快速搞定。
可以设置n个UART 发送器,每一路都发送自己的PIN NAME 比方说E12这个FPGA引脚发送E12这个字符串,这样就可以对照扩展板子上的引脚字符对应,确定是否正确。
现在问题是做一个UART 发送器, 要求参数化,能传递一个字符串,我们可以规定为 4个字符串 。四个字符来表达FPGA的引脚号足够。
从网络找到这么一段参数传递的例子。
module dma_controller #(
parameter integer C0_MAX_MIG_BL[3:0] = {2048,2048,2048,2048},
parameter integer C0_APP_DATA_WIDTH[3:0] = {64,64,64,64} ,
parameter integer C0_DMA_WR_DATA_WIDTH[3:0] = {16,16,16,16} ,
parameter integer C0_DMA_RD_DATA_WIDTH[3:0] = {16,16,16,16} ,
parameter [1 : 8*11] C0_READ_WRITE[3:0] = {"Write Only","Bidirection","Bidirection","Bidirection"},
parameter integer C1_MAX_MIG_BL[3:0] = {2048,2048,2048,2048},
parameter integer C1_APP_DATA_WIDTH[3:0] = {128,128,128,128} ,
parameter integer C1_DMA_WR_DATA_WIDTH[3:0] = {32,32,32,32} ,
parameter integer C1_DMA_RD_DATA_WIDTH[3:0] = {32,32,32,32} ,
parameter [1 : 8*11] C1_READ_WRITE[3:0] = {"Write Only","Bidirection","Bidirection","Bidirection"}
) (
parameter [1 : 8*11] C1_READ_WRITE[3:0] = {"Write Only","Bidirection","Bidirection","Bidirection"}
这句是定义了多了字符串,我们只定义一个就尝试简化为:
parameter [1 : 8*4] PIN_NAME = "AB12";
之后考虑做一个简单的UART发送器,由于这n个发送器使用同样的波特率,因此可以使用同一个计数器产生一个位同步脉冲信号 pulse .
100M时钟,产生9600的波特率,就是用100*1000*1000 除以 9600 。得到一个 10416.666 就是 10417 。
reg [31:0] c; always @ (posedge clk) if ( c== 10416) c<=0;else c<=c+1;
reg pulse ; always @ (posedge clk) pulse <=c== 10416;
之后我们做一个发送器,这个发送器循环发送6个字符,4个PIN NAME ,后面两个发送 13 10,也就是回车换行,也就是\r\n, 也就是 'h13 'h10 .
每一个字节我们设置12个bit,其中一个开始位0,之后8个数据位,之后一个停止位,2个空闲位,(可以理解成3个停止位)。加入两个空闲位是为了让串口通讯更加稳定。
每个字节12个bit,那么6个字节就是72个BIT,所以我们设置一个 计数器,从0-71循环。
reg [ 7:0 ] bit_cnt ; always @(posedge clk) if (pulse) bit_cntr <= (bit_cntr == 71 ) ?0:(bit_cntr + 1 ) ;
这个计数器主要是同步作用,我们在设置一个72位的串行移位寄存器,每个pluse 就是左移一位,当bit_cntr==0的时候从新加载72个bit位。
这72位实际是6个字节扩展过来的
reg [71:0] sft_reg ;
module chk_ext_io(
input clk ,
output AB12
);
`define OVF = (1000*1000*100 )/9600 ;
reg [31:0] c;
always@ (posedge clk) if (c == `OVF ) c<=0;else c<=1+c;
reg pulse ;
always @ (posedge clk) pulse <= c =`OVF ;
tx_node # ( .PIN_NAME ("AB12"))i_txnode( .clk(clk), .pulse(pulse) ,.tx(AB12) );
endmodule
module tx_node # (
parameter [1:6*8]PIN_NAME = "AB12"
)( input clk, pulse ,output reg tx);
wire [7:0] byte0 = swap8 ( PIN_NAME[1:8] ) ;
wire [7:0] byte1 = swap8 ( PIN_NAME[9:16] ) ;
wire [7:0] byte2 = swap8 ( PIN_NAME[17:24] ) ;
wire [7:0] byte3 = swap8 ( PIN_NAME[25:32] ) ;
reg [ 7:0 ] bit_cnt ; always @(posedge clk) if (pulse) bit_cntr <= ( bit_cntr == 71 ) ? 0 : ( bit_cntr + 1 ) ;
reg [71:0] sft_reg ;
always @ (posedge clk) if (pulse & ~|bit_cntr )
sft_reg <= { 'b0 , byte0[7:0], 'b11 , 'b0 ,byte1[7:0], 'b11 , 'b0 , byte2[7:0], 'b11 , 'b0 , byte3[7:0], 'b11 , 'b0 , 'h0d, 'b11 , 'b0 , 'h0a, 'b11 }
else sft_reg <= { sft_reg[70:1] ,1'b1 } ;
reg tx; always @(posedge clk) tx<=sft_reg[71] ;
function [31:0]swap8; //函数定义。
input [3:0] inbyte;
begin
swap8 = {inbyte[0] , inbyte[1] , inbyte[2] , inbyte[3] , inbyte[4] , inbyte[5] , inbyte[6] , inbyte[7] } ;
end
endfunction
endmodule
先写到这里,稍晚调试。