并行是指多比特数据同时通过并行线进行传送,这样数据传送速度大大提高,但并行传送的线路长度受到限制,因为长度增加,干扰就会增加,数据也就容易出错。
异步并口应用:CPU类的芯片与FPGA的数据交互,数据速率一般在100Mbps以内。数据总线不大于16bit。
非CPU类的功能芯片与FPGA通过并口进行数据交互,例如配置寄存器等等。
并行由于数据传输的相位差之间的正确窗口大小限制其传输速度。
这里提出亚稳态的概念,从事多时钟设计的第一步是要理解信号稳定性问题。当一个信号跨越某个时钟域时,对新时钟域的电路来说它就是一个异步信号。接收该信号的电路需要对其进行同步,同步可以防止第一级存储单元(触发器)的亚稳态在新的时钟域传播蔓延。
亚稳态是指触发器无法在某个规定时间段内达到一个可确认的状态。当一个触发器进入亚稳态时,既无法预测单元的输出电平也无法预测何时输出才能稳定在某个正确的电平上。在这个稳定期间,触发器输出一些中间级电平或者处于振荡状态,并且这种无用的输出电平可以沿信号通道上的各个触发器级联式传播下去。

代码实现:
module parall_inerf(input wire sclk,input wire rst_n,input wire cs_n,input wire rd_n,input wire wr_n,inout tri [15:0] data,input wire [7:0] addr);reg [15:0] data_0,data_1,data_2,data_3,data_4,data_5,data_6,data_7;reg [1:0] cs_n_r,rd_n_r,wr_n_r;reg [47:0] data_r;reg [23:0] addr_r;reg [15:0] rdata;//降低亚稳态出现概率,把CS_n,rd_n,wr_n,单比特信号打两拍always @(posedge sclk or negedge rst_n)if(rst_n==1'b0){cs_n_r,rd_n_r,wr_n_r}<=9'h1ff;else{cs_n_r,rd_n_r,wr_n_r}<={{cs_n_r[1:0],cs_n},{rd_n_r[1:0],rd_n},{wr_n_r[1:0],wr_n}};//降低亚稳态出现概率,always @(posedge sclk or negedge rst_n)if(rst_n==1'b0) begindata_r<=48'd0;addr_r<=24'd0;endelse begindata_r<={data_r[31:0],data};addr_r<={addr_r[15:0],addr};end//写always @(posedge sclk or negedge rst_n)if(rst_n==1'b0) begindata_0<=8'd0;data_1<=8'd0;data_2<=8'd0;data_3<=8'd0;data_4<=8'd0;data_5<=8'd0;data_6<=8'd0;data_7<=8'd0;endelse if{cs_n_r[2] == 1'b0 && rd_n_r[2] == 1'b1 && wr_n_r[2] == 1'b0} begincase(addr_r[23:16])8'd0:data_0<=data_r[47:32];8'd0:data_1<=data_r[47:32];8'd0:data_2<=data_r[47:32];8'd0:data_3<=data_r[47:32];8'd0:data_4<=data_r[47:32];8'd0:data_5<=data_r[47:32];8'd0:data_6<=data_r[47:32];8'd0:data_7<=data_r[47:32];dafaulet:begindata_0<=data_0;data_1<=data_1;data_2<=data_2;data_3<=data_3;data_4<=data_4;data_5<=data_5;data_6<=data_6;data_7<=data_7;endendcaseendalways @(posedge sclk or negedge rst_n)if(rst_n==1'b0) beginr_data<='d0;else if(cs_n_r[2] == 1'b0 && wr_n_r[2] == 1'b1)begincase(addr[23:16])8'd0:rdata=data_0;8'd0:rdata<=data_1;8'd0:rdata<=data_2;8'd0:rdata<=data_3;8'd0:rdata<=data_4;8'd0:rdata<=data_5;8'd0:rdata<=data_6;8'd0:rdata<=data_7;default:rdata<=16'd0;endcase//三态门assign data=(cs_n_r[2] == 1'b0 && rd_n_r[2]==1'b0)?rdata:16'hzzz;endmodule
代码测试:
1ns/1nsmodule tb_parall_interf();reg sclk,rst_n;reg cs_n,rd_n,wr_n;reg [15:0] data;reg [7:0] addr;reg [15:0] w_date;parameter setup_time=2;parameter hold_time=2;parameter data_time=4;=2;initial beginsclk=0;rst_n=0;#200rst_n=1;end=~sclk;//例化parall_interf parall_interf_inst((sclk),(rst_n),(cs_n),(rd_n),(wr_n),(w_data),.addr (addr));initial begincs_n=1;rd_n=1;wr_n=1;data=0;addr=0;rst_n);#100write_data(8);#100read_data(8);end//写数据任务task write_data(len);integer i,len;begin=0;i<len;i=i+1)begincs_n=0;data=i[15:0];addr=i[7:0];setup_dly();wr_n=0;data_dly();wr_n=1;hold_dly();=1;endcs_n=1;endendtask//读数据任务task read_data(len);integer i,len;begin=0;i<len;i=i+1)begincs_n=0;addr=i[7:0];read_dly();rd_n=0;data_dly();addr=%d data=%d",i,w_data);rd_n=1;endcs_n=1;endendtask//测试激励的三态门assign w_data=(wr_n==1'b0)?data:16'hzzzz;//延时task setup_dly();integer i;beginfor (i=0;i<setup_time;i=i+1)beginsclk);endendendtasktask hold_dly();integer i;begin=0;i<hold_time;i=i+1)beginsclk);endendendtasktask data_dly();integer i;begin=0;i<data_time;i=i+1)beginsclk);endendendtasktask read_dly();integer i;begin=0;i<read_time;i=i+1)beginsclk);endendendtaskendmodule