rtl代码
//地址:
// 3'b000:counter0[7:0]<=pwdata;
// 3'b001:counter0[15:8]<=pwdata;
// 3'b010:counter1[7:0]<=pwdata;
// 3'b011:counter1[15:8]<=pwdata;
// 3'b100:counter2[7:0]<=pwdata;
// 3'b101:counter2[15:8]<=pwdata;
// 110时为ctr
// ctr[0]为enable0
// ctr[1]为enable1
// ctr[2]为enable2
///////////////
//中断只是一个信号
////////////
//apb3全为写
module time_top(
//input
timer0_clk,
timer1_clk,
timer2_clk,
pclk,
rest,
paddr,
pwdata,
psel,
penable,
pwrite,////apb3全为写
//output
pready,
ti0,//timer0 interrupt
ti1,//timer1 interrupt
ti2//timer2 interrupt
);
input timer0_clk,timer1_clk,timer2_clk,pclk,rest,psel,penable,pwrite;
input[2:0] paddr;
input[7:0] pwdata;
output reg ti0,ti1,ti2;
output pready;
reg ctr;//控制字
reg[15:0] counter0;
reg[15:0] counter1;
reg[15:0] counter2;//计数器
reg pready0,pready1,pready2,pready_ctr;
//用于多时钟
reg timer0_clk_reg0,timer0_clk_reg1,timer1_clk_reg0,timer1_clk_reg1,timer2_clk_reg0,timer2_clk_reg1;
wire clk0,clk1,clk2;
//控制字
wire enable0,enable1,enable2;
//counter0
always@(posedge pclk or posedge rest)
if(rest)
begin
pready0<=1'b0;
counter0<=16'b0000_0000_0000_0000;
ti0<=1'b0;
end
else
begin
counter0<=counter0;
pready0<=1'b0;
ti0<=1'b0;
if(psel&(!penable))
begin
pready0<=1'b1;
case(paddr)
3'b000:counter0[7:0]<=pwdata;
3'b001:counter0[15:8]<=pwdata;
default:counter0<=counter0;
endcase
end
else
if(clk0&enable0)
begin
if(counter0==16'b1111_1111_1111_1111)
begin
counter0<=0000_0000_0000_0000;
ti0<=1'b1;
end
else
counter0<=counter0+1'b1;
end
end
always@(posedge pclk or posedge rest)
if(rest)
begin
timer0_clk_reg0<=1'b0;
timer0_clk_reg1<=1'b0;
end
else
begin
timer0_clk_reg0<=timer0_clk;
timer0_clk_reg1<=timer0_clk_reg0;
end
assign clk0=(~timer0_clk_reg0)&timer0_clk_reg1;
//counter1
always@(posedge pclk or posedge rest)
if(rest)
begin
ti1<=1'b0;
pready1<=1'b0;
counter1<=16'b0000_0000_0000_0000;
end
else
begin
counter1<=counter1;
ti1<=1'b0;
pready1<=1'b0;
if(psel&(!penable))
begin
pready1<=1'b1;
case(paddr)
3'b010:counter1[7:0]<=pwdata;
3'b011:counter1[15:8]<=pwdata;
default:counter1<=counter1;
endcase
end
else
if(clk1&enable1)
begin
if(counter1==16'b1111_1111_1111_1111)
begin
counter1<=0000_0000_0000_0000;
ti1<=1'b1;
end
else
counter1<=counter1+1'b1;
end
end
always@(posedge pclk or posedge rest)
if(rest)
begin
timer1_clk_reg0<=1'b0;
timer1_clk_reg1<=1'b0;
end
else
begin
timer1_clk_reg0<=timer1_clk;
timer1_clk_reg1<=timer1_clk_reg0;
end
assign clk1=(~timer1_clk_reg0)&timer1_clk_reg1;
//counter2
always@(posedge pclk or posedge rest)
if(rest)
begin
ti2<=1'b0;
pready2<=1'b0;
counter2<=16'b0000_0000_0000_0000;
end
else
begin
counter2<=counter2;
ti2<=1'b0;
pready2<=1'b0;
if(psel&(!penable))
begin
pready2<=1'b1;
case(paddr)
3'b100:counter2[7:0]<=pwdata;
3'b101:counter2[15:8]<=pwdata;
default:counter2<=counter2;
endcase
end
else
if(clk2&enable2)
begin
if(counter2==16'b1111_1111_1111_1111)
begin
counter2<=0000_0000_0000_0000;
ti2<=1'b1;
end
else
counter2<=counter2+1'b1;
end
end
always@(posedge pclk or posedge rest)
if(rest)
begin
timer2_clk_reg0<=1'b0;
timer2_clk_reg1<=1'b0;
end
else
begin
timer2_clk_reg0<=timer2_clk;
timer2_clk_reg1<=timer2_clk_reg0;
end
assign clk2=(~timer2_clk_reg0)&timer2_clk_reg1;
//pready
assign pready="pready0|pready1|pready2|pready"_ctr;
//ctr
always@(posedge pclk or posedge rest)
if(rest)
begin
ctr<=8'b0000_0000;
pready_ctr<=1'b0;
end
else
begin
pready_ctr<=1'b0;
if(psel&(!penable)&(paddr==3'b110))
begin
pready_ctr<=1'b1;
ctr<=pwdata;
end
end
//enable0/1/2
assign enable0=ctr[0];
assign enable1=ctr[1];
assign enable2=ctr[2];
endmodule
测试文件:
`timescale 1 ns / 1 ps
module testbench();
//////////////////////////////////////////////////////////
reg rest;
reg pclk;
reg pwrite;
reg psel;
reg penable;
reg timer0_clk,timer1_clk,timer2_clk;
reg[2:0] paddr;
reg[7:0] pwdata;
//////////////////////////////////////////////////////////
wire pready;
wire ti0;
wire ti1;
wire ti2;
////////////////////////////////////////////////////////
time_top uu1(
//input
.timer0_clk(timer0_clk),
.timer1_clk(timer1_clk),
.timer2_clk(timer2_clk),
.rest(rest),
.pclk(pclk),
.paddr(paddr),
.pwdata(pwdata),
.pwrite(pwrite),
.psel(psel),
.penable(penable),
//output
.pready(pready),
.ti0(ti0),
.ti1(ti1),
.ti2(ti2)
);
initial
begin
timer0_clk=1'b0;
timer1_clk=1'b0;
timer2_clk=1'b0;
rest=1'b1;
pclk=1'b0;
pwrite=1'b0;
psel=1'b0;
penable=1'b0;
paddr=3'b00000;
pwdata="8"'b0000_0000;
# 300 rest="1"'b0;
# 50
//写入计数器0的初值
cpu_write(3'b000,8'b1000_0010); //写低字节
# 10 cpu_write(3'b001,8'b1111_1111);//写矢咦纸? # 10 cpu_write(3'b110,8'b0000_0001);//写控制字,让计数器0工作
# 14000 $stop;
end
//clock
always
begin
# 50 timer0_clk=~timer0_clk;
end
always
begin
# 150 timer1_clk=~timer1_clk;
end
always
begin
# 300 timer2_clk=~timer2_clk;
end
always
begin
# 5 pclk=~pclk;
end
task cpu_write;
input [4:0] address;
input [7:0] data;
begin
// $display("CPU Write %04x = %04x",address,data);
@(negedge pclk);
pwrite = 1'b0;
@(negedge pclk);
penable = 1'b0;
psel = 1'b1;
paddr= address;
pwdata = data;
pwrite = 1'b1;
@(negedge pclk);
penable = 1'b1;
@(negedge pclk);
pwrite = 1'b0;
penable = 1'b0;
psel = 1'b0;
end
endtask
endmodule
文章评论(0条评论)
登录后参与讨论