📄 parallel.v
字号:
/***Local Bus Interface*********************************************************/
//外接VSC7324
module parallel_interface (
clock,reset_n,
addr_in,data_in,data_out,ready_n,
l_cmdo,abort_n,lt_framen,lt_ackn,lt_dxfrn,lt_tsr,
pi_addr,pi_data,dir,oe_a,oe_d,
//zarlink
cpu_cs_n,cpu_oe_n,cpu_we_n,
cpu_ts_ale,cpu_ta_n,cpu_clk,
//cpld
cpld_cs,cpld_wr,cpld_rd,
//rtc
rtc_ad,rtc_cs_n,rtc_as,rtc_rw,rtc_ds,rtc_sqw,
ot_cnt
);
input clock;
input reset_n;
//Back end Interface from "pci_top"
input [21:0] addr_in;
input [31:0] data_in;
output [31:0] data_out;
output ready_n;
inout [3:0] l_cmdo;
output abort_n;
input lt_framen;
input lt_ackn;
input lt_dxfrn;
input [11:0] lt_tsr;
//Parallel Interface
output [21:0] pi_addr;
inout [31:0] pi_data;
output dir;
output oe_a;
output oe_d;
//zarlink
output cpu_cs_n;
output cpu_oe_n;
output cpu_we_n;
output cpu_ts_ale;
input cpu_ta_n;
output cpu_clk;
//cpld
output cpld_cs;
output cpld_wr;
output cpld_rd;
//rtc
inout [7:0] rtc_ad;
output rtc_cs_n;
output rtc_as;
output rtc_rw;
output rtc_ds;
input rtc_sqw;
output [31:0] ot_cnt;//Over time error counter
//
// output test_flag;//For test
// input [7:0] ot_thr;//Overtime threshold (wait for pi_done_n)
//output [31:0] ot_cnt;//Over time error counter
reg [31:0] ot_cnt;
/******************************************************************************/
`define BAR0 (lt_tsr[0] == 1'b1) //Local
`define BAR1 (lt_tsr[1] == 1'b1) //zarlink
`define BAR2 (lt_tsr[2] == 1'b1) //RTC
`define BAR3 (lt_tsr[3] == 1'b1) //cpld
//`define BAR4 (lt_tsr[4] == 1'b1) //NA
//`define BAR5 (lt_tsr[5] == 1'b1) //NA
`define mem_read (l_cmdo == 4'b0110)
`define mem_write (l_cmdo == 4'b0111)
`define ot_thr 8'b00100000 //Overtime threshold (wait for pi_done_n)
/******************************************************************************/
reg [31:0] pi_data_reg;
reg [21:0] pi_addr;
//back
reg ready_n;
reg abort_n;
//zar
reg cpu_cs_n;
reg cpu_oe_n;
reg cpu_we_n;
reg cpu_ts_ale;
//cpld
reg cpld_cs;
reg cpld_wr;
reg cpld_rd;
//rtc
// reg rtc_ad;
reg rtc_ad_ie;//input enable
reg rtc_ad_oe;//output enable
reg rtc_cs_n;
reg rtc_as;
reg rtc_rw;
reg rtc_ds;
reg [3:0] rtc_counter;
reg [7:0] rtc_ad_out_reg;
/******************************************************************************/
wire oe;//Enable pi_data output to IC
assign cpu_clk = clock;
// assign oe_a = 1'b0;
// assign oe_d = 1'b0;
assign dir = ! ((`BAR1 || `BAR3) && `mem_read);//read 0;write 1
// ascpldn oe = (`mem_write && (`BAR1 || `BAR2 || `BAR3 || `BAR4 || `BAR5));
assign oe = (`mem_write && (`BAR1 ||`BAR2 ||`BAR3));
assign pi_data = oe ? pi_data_reg : 32'hz;
assign rtc_ad = (rtc_ad_oe) ? rtc_ad_out_reg : 8'hz;
// assign data_out = (!oe) ? pi_data : 32'h0;
assign data_out = ((rtc_ad_ie) ? {24'h0 , rtc_ad} : (!oe) ? pi_data : 32'h0);
/******************************************************************************/
//addr_in 锁存
always @(posedge clock or negedge reset_n)
begin
if(!reset_n)
pi_addr <= 22'h0;
else
begin
if(!lt_framen && (`mem_write || `mem_read) )
begin
pi_addr <= addr_in;
end
/* else if(!lt_framen && (`mem_write || `mem_read) && `BAR2)
begin
pi_addr[7:0]<=addr_in[7:0];
end */
else ;
end
end
/******************************************************************************/
//data_in 锁存
always @(negedge lt_dxfrn or negedge reset_n)
begin
if(!reset_n)
pi_data_reg <= 32'h0;
else
begin
if(`mem_write )//&& `BAR1)
pi_data_reg <= data_in;
/* else if(`mem_write && `BAR3)
pi_data_reg[7:0]<=data_in[7:0];
else ;*/
else;
end
end
/******************************************************************************/
//State machine
reg [7:0] ot_count;//Overtime counter
reg [13:0] cstate;
parameter [13:0]
IDLE = 14'b00_0000_0000_0001,
READ_ZAR = 14'b00_0000_0000_0010,
READ_ZAR_1 = 14'b00_0000_0000_0100,
READ_ZAR_2 = 14'b00_0000_0000_1000,
WRITE_ZAR = 14'b00_0000_0001_0000,
WRITE_ZAR_1 = 14'b00_0000_0010_0001,
WRITE_ZAR_2 = 14'b00_0000_0100_0000,
WRITE_ZAR_3 = 14'b00_0000_1000_0000,
RTC_RD = 14'b00_0001_0000_0000,
RTC_WR = 14'b00_0010_0000_0000,
READ_CPLD = 14'b00_0100_0000_0000,
READ_CPLD_1 = 14'b00_1000_0000_0000,
WRITE_CPLD = 14'b01_0000_0000_0000,
WRITE_CPLD_1= 14'b10_0000_0000_0000;
/******************************************************************************/
always @(posedge clock or negedge reset_n)
begin
if(!reset_n)
begin
ready_n <= 1'b1;
abort_n <=1'b1;
//zar
cpu_we_n <= 1'b1;
cpu_oe_n <= 1'b1;
cpu_cs_n <= 1'b1;
cpu_ts_ale <= 1'b0;
//cpld
cpld_cs <= 1'b1;
cpld_wr <= 1'b1;
cpld_rd <= 1'b1;
//rtc
rtc_ad_ie <= 1'b0;
rtc_ad_oe <= 1'b0;
rtc_cs_n <= 1'b1;
rtc_as <= 1'b0;
rtc_rw <= 1'b1;
rtc_ds <= 1'b1;
rtc_counter <= 8'h0;
rtc_ad_out_reg <= 8'h0;
ot_count <= 8'b0;
ot_cnt <= 32'b0;
// test_flag <= 1'b0;
cstate <= IDLE;
end
else
begin
case(cstate)
IDLE:
begin
rtc_counter <= 8'h0;
rtc_ds <= 1'b1;
rtc_rw <= 1'b1;
rtc_cs_n <= 1'b1;
rtc_ad_ie <= 1'b0;
rtc_ad_oe <= 1'b0;
ot_count <= 8'b0;
if(!lt_framen && `mem_read && (`BAR1)) //zar read
begin
cpu_we_n <= 1'b1; //开始读操作
cpu_oe_n <= 1'b0; //使能zl的读信号(read=0)
cpu_cs_n <= 1'b0; //片选有效
cpu_ts_ale <= 1'b1; //地址锁存有效
cstate <= READ_ZAR; //此时frame信号有效
end
else if(!lt_framen && `mem_write && (`BAR1)) //zar write
begin
ready_n <= 1'b0; //接收端已经准好了接收数据
cpu_oe_n <= 1'b1;
cpu_we_n <= 1'b0;
cpu_cs_n <= 1'b0; //地址片选有效
cpu_ts_ale <= 1'b1; //地址锁存有效
cstate <= WRITE_ZAR;//CS 触发
end
// else if(!lt_framen && `mem_write && (1'b0))
// begin
// ready_n <= 1'b0;
// cstate <= WRITE2;//WR 触发
// end
else if(!lt_framen && `mem_read && (`BAR2)) //rtc read
begin
//ready_n <= 1'b0;
cstate <= RTC_RD;//RTC read
end
else if(!lt_framen && `mem_write && (`BAR2)) //rtc write
begin
ready_n <= 1'b0;
cstate <= RTC_WR;//RTC write
end
else if(!lt_framen && `mem_read && `BAR3) //cpld read
begin
cpld_cs <= 1'b0;
cpld_rd <= 1'b0;
cpld_wr <= 1'b1;
// ready_n <= 1'b0;
cstate <= READ_CPLD;
end
else if(!lt_framen && `mem_write && `BAR3) //cpld write
begin
ready_n <= 1'b0;
cpld_cs <= 1'b0;
cpld_wr <= 1'b0;
cpld_rd <= 1'b1;
cstate <= WRITE_CPLD;
end
else
begin
ready_n <= 1'b1;
abort_n <=1'b1;
//zar
cpu_we_n <= 1'b1;
cpu_oe_n <= 1'b1;
cpu_cs_n <= 1'b1;
cpu_ts_ale <= 1'b0;
//cpld
cpld_cs <= 1'b1;
cpld_wr <= 1'b1;
cpld_rd <= 1'b1;
//rtc
rtc_ad_ie <= 1'b0;
rtc_ad_oe <= 1'b0;
rtc_cs_n <= 1'b1;
rtc_as <= 1'b0;
rtc_rw <= 1'b1;
rtc_ds <= 1'b1;
rtc_counter <= 8'h0;
rtc_ad_out_reg <= 8'h0;
cstate <= IDLE;
end
end
READ_ZAR:
begin
cpu_ts_ale <= 1'b1;
cpu_cs_n <= 1'b0;
cpu_oe_n <= 1'b0;
cstate <= READ_ZAR_1;
end
READ_ZAR_1:
begin
cpu_ts_ale <= 1'b0;
ot_count <= ot_count + 1 ;
if(ot_count == `ot_thr)
begin
ready_n <= 1'b1;
abort_n <= 1'b0;
ot_count <= 8'b0;
ot_cnt <= ot_cnt + 1;
cstate <= IDLE;
end
else if(!cpu_ta_n) //本地数据准好了,可以读入,等待本地总线准备好!
begin
ready_n <= 1'b0; //local bus 准备好
ot_count <= 8'b0;
cstate <= READ_ZAR_2;
end
else
cstate <= READ_ZAR_1;
end
READ_ZAR_2:
begin
ot_count <= ot_count + 1 ;
if(ot_count == `ot_thr)
begin
abort_n <= 1'b0;
ot_count <= 8'b0;
ot_cnt <= ot_cnt + 1;
ready_n <= 1'b1;
cstate <= IDLE;
end
else if(!lt_framen) //只有等frame信号无效时,本地数据才真正的传输到PCI总线上去。
cstate <= READ_ZAR_2; //等待PCI总线把数据读完,以便进行下一此数据的读写。
else
begin
cpu_oe_n <= 1'b1;
cpu_cs_n <= 1'b1;
ot_count <= 8'b0;
ready_n <= 1'b1;
cstate <= IDLE;
end
end
WRITE_ZAR:
begin
cpu_ts_ale <= 1'b1;
cpu_cs_n <= 1'b0;
cpu_we_n <= 1'b0; //本地能有效
// cpu_ts_ale <= 1'b1; //地址锁存到本地端
cstate <= WRITE_ZAR_1;
end
WRITE_ZAR_1:
begin
cpu_ts_ale <= 1'b0;
ot_count <= ot_count + 1 ;
if(ot_count == `ot_thr)
begin
ready_n <= 1'b1;
abort_n <=1'b0;
ot_count <= 8'b0;
ot_cnt <= ot_cnt + 1;
cstate <= IDLE;
end
else if(!lt_dxfrn) //等数据到local端,到了之后就交给本地端进行时序控制!
begin
ready_n <= 1'b1; //数据到了local端,那么不使能local端。
ot_count <= 8'b0;
cstate <= WRITE_ZAR_2;
end
else
begin
cstate <= WRITE_ZAR_1;
end
end
WRITE_ZAR_2:
begin
ot_count <= ot_count + 1 ;
if(ot_count == `ot_thr)
begin
abort_n <=1'b0;
ot_count <= 8'b0;
ot_cnt <= ot_cnt + 1;
ready_n <= 1'b1;
cstate <= IDLE;
end
else if(!cpu_ta_n) //数据已经到了local端,等待本地端有效接收
begin
// cpu_we_n <= 1'b1; //本地接收到数据之后,就禁止再写入数据。
ot_count <= 8'b0;
cstate <= WRITE_ZAR_3;
end
else
begin
cstate <= WRITE_ZAR_2;
end
end
WRITE_ZAR_3: //数据已经处理完了,恢复到空闲状态!
begin
cpu_we_n <= 1'b1;
cpu_cs_n <= 1'b1;
// ready_n <= 1'b1;
cstate <= IDLE;
end
/* WRITE2:
begin
ot_count <= ot_count + 1 ;
if(ot_count == ot_thr)
begin
ready_n <= 1'b1;
abort_n <=1'b0;
ot_count <= 8'b0;
ot_cnt <= ot_cnt + 1;
cstate <= IDLE;
end
else if(!lt_dxfrn)
begin
pi_wr <= 1'b0;
pi_cs_n[5] <= 1'b0;
ready_n <= 1'b1;
ot_count <= 8'b0;
cstate <= W2_WAIT;
end
else
cstate <= WRITE2;
end
W2_WAIT:
begin
ot_count <= ot_count + 1 ;
if(ot_count == ot_thr)
begin
abort_n <=1'b0;
ot_count <= 8'b0;
ot_cnt <= ot_cnt + 1;
cstate <= IDLE;
end
else if(!pi_done_n_wire)
begin
pi_wr <= 1'b1;
pi_cs_n[5] <= 1'b1;
ot_count <= 8'b0;
cstate <= IDLE;
end
else
cstate <= W2_WAIT;
end
*/
RTC_RD:
begin
rtc_counter <= rtc_counter + 1'b1;
if(rtc_counter == 1) begin
rtc_ad_out_reg <= addr_in[7:0];
rtc_as <= 1'b1;
rtc_cs_n <= 1'b0;
rtc_ad_oe <= 1'b1; end
else if(rtc_counter == 3) begin
rtc_as <= 1'b0; end
else if(rtc_counter == 6) begin
rtc_ds <= 1'b0;
rtc_ad_oe <= 1'b0; end
else if(rtc_counter == 9) begin
ready_n <= 1'b0;
rtc_ad_ie <= 1'b1; end
else if(rtc_counter == 11) begin
ready_n <= 1'b1;
rtc_ad_ie <= 1'b0;
rtc_ds <= 1'b1; end
else if(rtc_counter == 12) begin
rtc_cs_n <= 1'b1;
cstate <= IDLE; end
else begin
cstate <= RTC_RD; end
end
RTC_WR:
begin
rtc_counter <= rtc_counter + 1'b1;
if(rtc_counter == 1) begin
rtc_ad_out_reg <= addr_in[7:0];
rtc_as <= 1'b1;
rtc_cs_n <= 1'b0;
rtc_ad_oe <= 1'b1; end
else if(rtc_counter == 3) begin
ready_n <= 1'b1;
rtc_as <= 1'b0; end
else if(rtc_counter == 6) begin
rtc_ad_out_reg <= pi_data_reg[7:0];
rtc_rw <= 1'b0; end
else if(rtc_counter == 11) begin
rtc_cs_n <= 1'b1;
rtc_rw <= 1'b1; end
else if(rtc_counter == 12) begin
rtc_ad_out_reg <= 8'h0;
rtc_ad_oe <= 1'b0;
cstate <= IDLE; end
else begin
cstate <= RTC_WR; end
end
READ_CPLD:
begin
ot_count <= ot_count + 1 ;
if(ot_count == 8'b00000010) //等待90nS
begin
ot_count <= 8'b0;
ready_n <= 1'b0;
cstate <= READ_CPLD_1;
end
else
cstate <= READ_CPLD;
end
READ_CPLD_1:
begin
ot_count <= ot_count + 1 ;
if(ot_count == `ot_thr)
begin
abort_n <= 1'b0;
ot_count <= 8'b0;
ot_cnt <= ot_cnt + 1;
ready_n <= 1'b1;
cstate <= IDLE;
end
else if(!lt_framen)
cstate <= READ_CPLD_1;
else
begin
cpld_cs <= 1'b1;
cpld_wr <= 1'b1;
cpld_rd <= 1'b1;
ot_count <= 8'b0;
ready_n <= 1'b1;
cstate <= IDLE;
end
end
WRITE_CPLD:
begin
ot_count <= ot_count + 1 ;
if(ot_count == `ot_thr)
begin
ready_n <= 1'b1;
abort_n <=1'b0;
ot_count <= 8'b0;
ot_cnt <= ot_cnt + 1;
cstate <= IDLE;
end
else if(!lt_dxfrn)
begin
cpld_cs <= 1'b1;
ready_n <= 1'b1;
ot_count <= 8'b0;
cstate <= WRITE_CPLD_1;
end
else
cstate <= WRITE_CPLD;
end
WRITE_CPLD_1:
begin
ot_count <= ot_count + 1 ;
if(ot_count == 8'b00000011)
begin
ot_count <= 8'b0;
cpld_cs <= 1'b1;
cpld_wr <= 1'b1;
cpld_rd <= 1'b1;
ready_n <= 1'b1;
cstate <= IDLE;
end
else
cstate <= WRITE_CPLD_1;
end
default: cstate <= IDLE;
endcase
end
end
/******************************************************************************/
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -