注意看这个时序是没有clk的,这是因为localbus是解复用的,地址和数据线是同步传过来的所以不需要再由clk进行同步,知道了这个,在针对性的去写就很容易了。这是根据sc16c654进行模拟设计,所以可以这样陈旭如下:
module sc16c654(
input SYS_CLK , // (i) System Clock.
input SYS_RST , // (i) System Reset (high active)
//
input [2:0] addr , // (i) 三位地址对应相应寄存器
inout [7:0] date , // (io)数据
input CS_a , // (i) 片选a
input CS_b , // (i) 片选b
input CS_c , // (i) 片选c
input CS_d , // (i) 片选d
input lor , // (i) 读使能低有效
input low // (i) 写使能低有效
);
//打拍后续进行下降沿检测//ddf
reg CS_a_dff ;
reg CS_b_dff ;
reg CS_c_dff ;
reg CS_d_dff ;
reg [2:0] addr_dff ;
reg [7:0] date_dff ;
reg low_dff ;
ddf1
reg CS_a_dff_1;
reg CS_b_dff_1 ;
reg CS_c_dff_1 ;
reg CS_d_dff_1 ;
reg [2:0] addr_dff_1 ;
reg [7:0] date_dff_1 ;
reg low_dff_1 ;
reg CS_a_dff_2 ;
reg CS_b_dff_2 ;
reg CS_c_dff_2 ;
reg CS_d_dff_2 ;
reg low_dff_2 ;
//下降沿标志信号
wire s_CS_a_F ; //cs下降沿标志
wire s_CS_b_F ; //cs下降沿标志
wire s_CS_c_F ; //cs下降沿标志
wire s_CS_d_F ; //cs下降沿标志
wire s_WR_N_F ; //wr下降沿标志
reg r_WR_N_F ; //转变为寄存器形
//读相关
wire [7:0] s_RD_D ;
reg [7:0] r_RD_D ;
//***************************
//sc16c654 write reg
//初值
//3'b000: //初值//PHR==xx OR THR==xx OR DLL==xx
//3'b001: //LER==00 OR DLM==xx
//3'b010: //FCR==00 OR ISR==01 OR EFR==00
//3'b011: //LCR==00
//3'b100: //MCR==00
//***************************
reg [7:0]phr;
reg [7:0]thr;
reg [7:0]dll;
reg [7:0]ler;
reg [7:0]dlm;
reg [7:0]fcr;
reg [7:0]lsr;
reg [7:0]efr;
reg [7:0]lcr;
reg [7:0]mcr;
//dff1
always @ (posedge SYS_CLK or posedge SYS_RST) begin
if (SYS_RST) begin
CS_a_dff <= 1'b1 ;
CS_b_dff <= 1'b1 ;
CS_c_dff <= 1'b1 ;
CS_d_dff <= 1'b1 ;
addr_dff <= 3'b0; ;
date_dff <= 8'b0; ;
low_dff <= 1'b1; ;
end
else begin
CS_a_dff <= CS_a ;
CS_b_dff <= CS_b ;
CS_c_dff <= CS_c ;
CS_d_dff <= CS_d ;
addr_dff <= addr; ;
date_dff <= date; ;
low_dff <= low; ;
end
end
//dff2
always @ (posedge SYS_CLK or posedge SYS_RST) begin
if (SYS_RST) begin
CS_a_dff_1 <= 1'b1 ;
CS_b_dff_1 <= 1'b1 ;
CS_c_dff_1 <= 1'b1 ;
CS_d_dff_1 <= 1'b1 ;
addr_dff_1 <= 3'b0 ;
date_dff_1 <= 8'b0 ;
low_dff_1 <= 1'b1 ;
end
else begin
CS_a_dff_1 <= CS_a_dff ;
CS_b_dff_1 <= CS_b_dff ;
CS_c_dff_1 <= CS_c_dff ;
CS_d_dff_1 <= CS_d_dff ;
addr_dff_1 <= addr_dff ;
date_dff_1 <= date_dff ;
low_dff_1 <= low_dff ;
end
end
//
always @ (posedge SYS_CLK or posedge SYS_RST) begin
if (SYS_RST) begin
CS_a_dff_2 <= 1'b1 ;
CS_b_dff_2 <= 1'b1 ;
CS_c_dff_2 <= 1'b1 ;
CS_d_dff_2 <= 1'b1 ;
low_dff_2 <= 1'b1 ;
end
else begin
CS_a_dff_2 <=CS_a_dff_1 ;
CS_b_dff_2 <=CS_b_dff_1 ;
CS_c_dff_2 <=CS_c_dff_1 ;
CS_d_dff_2 <=CS_d_dff_1 ;
low_dff_2 <=low_dff_1 ;
end
end
assign s_CS_a_F = (CS_a_dff_1 == 1'b0 && CS_a_dff_2 == 1'b1) ? 1'b1 : 1'b0;
assign s_CS_b_F = (CS_b_dff_1 == 1'b0 && CS_b_dff_2 == 1'b1) ? 1'b1 : 1'b0;
assign s_CS_c_F = (CS_c_dff_1 == 1'b0 && CS_c_dff_2 == 1'b1) ? 1'b1 : 1'b0;
assign s_CS_d_F = (CS_d_dff_1 == 1'b0 && CS_d_dff_2 == 1'b1) ? 1'b1 : 1'b0;
assign s_WR_N_F = (low_dff_1 == 1'b0 && low_dff_2 == 1'b1) ? 1'b1 : 1'b0;
//对wr低有效标志位进一步寄存
always @ (posedge SYS_CLK or posedge SYS_RST) begin
if (SYS_RST) begin
r_WR_N_F <= 1'b0;
end else begin
r_WR_N_F <= s_WR_N_F;
end
end
always @ (posedge SYS_CLK or posedge SYS_RST) begin
if (SYS_RST) begin
phr<=2'hz;
thr<=2'hz;
dll<=2'hz;
ler<=2'h00;
dlm<=2'hz;
fcr<=2'h00;
lsr<=2'h01;
efr<=2'h00;
lcr<=2'h00;
mcr<=2'h00;
end
else begin
if (r_WR_N_F == 1'b1 && s_CS_a_F == 1'b0) begin
case (addr_dff_1)
3'b000 : begin
phr <= date_dff_1 ;
end
3'b001 : begin
thr <= date_dff_1 ;
end
3'b010 : begin
dll <= date_dff_1 ;
end
3'b011 : begin
ler <= date_dff_1 ;
end
endcase
end
end
end
assign s_RD_D = (addr_dff == 3'b000 ) ? phr :
(addr_dff == 3'b001) ? thr :
(addr_dff == 3'b010) ? dll :
(addr_dff == 3'b011) ? ler :8'b0;
always @ (posedge SYS_CLK or posedge SYS_RST) begin
if (SYS_RST) begin
r_RD_D <= 8'b0;
end else begin
if (s_CS_a_F == 1'b1) begin
r_RD_D <= s_RD_D;
end
end
end
assign date = (CS_a_dff_2 == 1'b0 && lor == 1'b0) ? r_RD_D : 8'bzzzzzzzz;
assign date = (CS_b_dff_2 == 1'b0 && lor == 1'b0) ? r_RD_D : 8'bzzzzzzzz;
assign date = (CS_c_dff_2 == 1'b0 && lor == 1'b0) ? r_RD_D : 8'bzzzzzzzz;
assign date = (CS_d_dff_2 == 1'b0 && lor == 1'b0) ? r_RD_D : 8'bzzzzzzzz;
endmodule
tb文件:
module sc1654_tb();
reg SYS_CLK ; // (i) System Clock.
reg SYS_RST ; // (i) System Reset (high active)
//
reg [2:0] addr ; // (i) 三位地址对应相应寄存器
wire [7:0] date ; // (io)数据
reg CS_a ; // (i) 片选a
reg CS_b ; // (i) 片选b
reg CS_c ; // (i) 片选c
reg CS_d ; // (i) 片选d
reg lor ; // (i) 读使能低有效
reg low ; // (i) 写使能低有效
sc16c654 test(
. SYS_CLK(SYS_CLK), // (i) System Clock.
. SYS_RST(SYS_RST), // (i) System Reset (high active)
. addr(addr ) , // (i) 三位地址对应相应寄存器
. date( date) , // (io)数据
. CS_a(CS_a ) , // (i) 片选a
. CS_b(CS_b ) , // (i) 片选b
. CS_c(CS_c ) , // (i) 片选c
. CS_d(CS_d ) , // (i) 片选d
. lor (lor ) , // (i) 读使能低有效
. low (low ) // (i) 写使能低有效
);
always #10 SYS_CLK = ~SYS_CLK;
initial begin
SYS_CLK = 1;
SYS_RST = 1;
addr =3'b111;
force date= 8'b0000_0000;
CS_a = 1'b1 ;
CS_b = 1'b1 ;
CS_c = 1'b1 ;
CS_d = 1'b1 ;
lor = 1'b1 ;
low = 1'b1 ;
//第一次写
SYS_RST = 0;
addr=3'b001;
force date= 8'b1010_1010;
CS_a = 1'b0 ;#21
low = 1'b0 ; #31
CS_a = 1'b1 ;#31
low = 1'b1 ; #21
//读
addr=3'b001;
CS_a = 1'b0 ;#21
lor = 1'b0 ; #31
CS_a = 1'b1 ;#21
lor = 1'b1 ; #31
//第二次写
SYS_RST = 0;
addr=3'b010;
force date= 8'b1100_0011;
CS_a = 1'b0 ;#21
low = 1'b0 ; #31
CS_a = 1'b1 ;#31
low = 1'b1 ; #21
//读
addr=3'b010;
CS_a = 1'b0 ;#21
lor = 1'b0 ; #31
CS_a = 1'b1 ;#21
lor = 1'b1 ; #31
#2000;
$stop;
end
endmodule
仿真图如下