APB Slave设计实践

目录

APB接口描述

APB写传输

APB读传输

APB Slave 设计

APB Slave testbench


APB接口描述

APB写传输

APB读传输

APB Slave 设计

module apb_slave(
                //input signals
                pclk,
                presetn,
                psel,
                penable,
                pwrite,
                pwdata,
                paddr,
                //output signals
                prdata
                 );

input         pclk   ;
input         presetn;
input         psel   ;
input         penable;
input         pwrite ;
input  [31:0] pwdata ;
input  [31:0] paddr  ;
output [31:0] prdata ;

parameter REG1_ADDR  = 8'h00;
parameter REG2_ADDR  = 8'h04;
parameter REG3_ADDR  = 8'h08;

reg [31:0] prdata    ;
wire       apb_write ;
wire       apb_read  ;
reg [31:0] reg1      ;
reg [31:0] reg2      ;
reg [31:0] reg3      ;
reg [31:0] dummy_reg ;
 
assign apb_write = pwrite && psel && penable ;
assign apb_read  = (!pwrite) && psel && penable;

//register write
always @(posedge pclk or negedge presetn)
begin
  if(!presetn)
    begin
      reg1 <= 32'b0;
      reg2 <= 32'b0;
      reg3 <= 32'b0;
    end
  else if(apb_write)
    begin
      case (paddr[7:0])
        REG1_ADDR : reg1      <= pwdata ;
        REG2_ADDR : reg2      <= pwdata ;
        REG3_ADDR : reg3      <= pwdata ;
        default   : dummy_reg <= pwdata ;
      endcase
    end
end


//register read
always @(*)
begin
   if(apb_read)
    begin
      case (paddr[7:0])
        REG1_ADDR : prdata <= reg1 ;
        REG2_ADDR : prdata <= reg2 ;
        REG3_ADDR : prdata <= reg3 ;
        default   : prdata <= dummy_reg ;
      endcase
    end
   else
     prdata = 32'b0;
end

endmodule
`timescale 1ns/1ps
module apb_slave_tb;

reg       pclk   ;
reg       presetn;
reg       psel   ;
reg       penable;
reg       pwrite ;
reg [31:0] pwdata;
reg [31:0] paddr ;
wire[31:0] prdata;

reg [31:0] rdata; 

//Rigster address
parameter REG1_ADDR  = 8'h00;
parameter REG2_ADDR  = 8'h04;
parameter REG3_ADDR  = 8'h08;


apb_slave U_apb_slave(
                .pclk          (pclk),
                .presetn        (presetn),
                .psel           (psel),
                .penable        (penable),
                .pwrite         (pwrite),
                .pwdata         (pwdata),
                .paddr          (paddr),
                .prdata         (prdata)
                );

//clock generate
initial begin
  pclk = 0 ;
  forever
  #10 pclk = ~pclk;
end

//reset generate
initial begin
   presetn = 0;
   #128;
   presetn = 1;
end

//initial statement
initial
begin
  psel      = 1'b0;
  penable   = 1'b0;
  pwrite    = 1'b0;
  paddr     = 32'b0;
  pwdata    = 32'b0;

  wait(presetn);

apb_write(REG1_ADDR,32'h12345678);
apb_read (REG1_ADDR,rdata);
#100;
apb_write(REG2_ADDR,32'h55aaaa55);
apb_read (REG2_ADDR,rdata);
#100;
apb_write(REG3_ADDR,32'h5201314a);
apb_read (REG3_ADDR,rdata);

#1000;
$finish;
end

task apb_write(input [7:0] addr,input [31:0]wdata);
  begin
    @(posedge pclk);  //T2
     #1;
     pwrite = 1'b1;
     psel   = 1'b1;
     penable= 1'b0;
     paddr  = addr;
     pwdata = wdata;
     
     @(posedge pclk);  //T3
     #1;
     penable= 1'b1;
 
     @(posedge pclk);  //T4
     #1;
     pwrite = 1'b0;
     psel   = 1'b0;
     penable= 1'b0;
     pwdata = 32'h0;
     @(posedge pclk);
     @(posedge pclk);
  end
endtask

  
task apb_read(input [7:0] addr,output [31:0]rdata);
  begin
    @(posedge pclk);  //T2
      #1;
    pwrite = 1'b0;
    psel   = 1'b1;
    penable= 1'b0;
    paddr  = addr;
    
    @(posedge pclk);  //T3
    #1;
    penable= 1'b1;
   
    @(posedge pclk);  //T4
    #1;
    rdata  = prdata;
    psel   = 1'b0;
    penable= 1'b0;
    @(posedge pclk);
  end
endtask

initial begin 
	$fsdbDumpfile("apb_slave.fsdb");
	$fsdbDumpvars(0);

end


endmodule

APB Slave testbench

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值