忻州市网站建设_网站建设公司_留言板_seo优化
2025/12/19 17:19:08 网站建设 项目流程

一、代码

AHB总线代码见我认识的AHB - Holybanban - 博客园

1.1 AHB2APB桥的接口

module ahb2apb1 #(parameter ADDR_WIDTH    = 32    ,parameter DATA_WIDTH    = 32    
)(
//systeminput  wire                     PCLK        ,input  wire                     PRESETn     ,
//apb slaveoutput wire [ADDR_WIDTH-1:0]    PADDR       ,output wire                     PSEL1       ,output wire                     PSEL2       ,output wire                     PENABLE     ,output wire                     PWRITE      ,output wire [DATA_WIDTH-1:0]    PWDATA      ,input  wire                     PREADYIN1   ,input  wire                     PREADYIN2   ,input  wire [DATA_WIDTH-1:0]    PRDATAIN1   ,input  wire [DATA_WIDTH-1:0]    PRDATAIN2   ,
//ahb masterinput  wire                     HSELx       ,input  wire [ADDR_WIDTH-1:0]    HADDR       ,input  wire [1:0]               HTRANS      ,input  wire                     HWRITE      ,input  wire [2:0]               HSIZE       ,input  wire [2:0]               HBURST      ,input  wire [DATA_WIDTH-1:0]    HWDATA      ,output wire [DATA_WIDTH-1:0]    PRDATAOUT   ,output wire                     PREADYOUT   
`ifdef RARELY_USED_SIGNALoutput wire [2:0]               PPROT       ,output wire                     PNSE        ,output wire [DATA_WIDTH/8-1:0]  PSTRB       ,output wire                     PWAKEUP     ,output wire [31:0]              PAUSER      ,output wire [DATA_WIDTH/2-1:0]  PWUSER      ,input  wire                     PSLVERR     ,input  wire [DATA_WIDTH/2-1:0]  PRUSER      ,input  wire [31:0]              PBUSER
`endif
);

1.2 AHB2APB1

目前只能适配AHB的Single读写传输,后续会加入AHB2APB2,作为AHB总线的第二个桥从机。

`timescale 1ns/1ps
/** Address Space* subordinate1 0x0000_0000~0x0000_ffff* subordinate2 0x0001_0000~0x0001_ffff*/
module ahb2apb1 #(parameter ADDR_WIDTH    = 32    ,parameter DATA_WIDTH    = 32    
)(
//systeminput  wire                     PCLK        ,input  wire                     PRESETn     ,
//apb slaveoutput wire [ADDR_WIDTH-1:0]    PADDR       ,output wire                     PSEL1       ,output wire                     PSEL2       ,output wire                     PENABLE     ,output wire                     PWRITE      ,output wire [DATA_WIDTH-1:0]    PWDATA      ,input  wire                     PREADYIN1   ,input  wire                     PREADYIN2   ,input  wire [DATA_WIDTH-1:0]    PRDATAIN1   ,input  wire [DATA_WIDTH-1:0]    PRDATAIN2   ,
//ahb masterinput  wire                     HSELx       ,input  wire [ADDR_WIDTH-1:0]    HADDR       ,input  wire [1:0]               HTRANS      ,input  wire                     HWRITE      ,input  wire [2:0]               HSIZE       ,input  wire [2:0]               HBURST      ,input  wire [DATA_WIDTH-1:0]    HWDATA      ,output wire [DATA_WIDTH-1:0]    PRDATAOUT   ,output wire                     PREADYOUT   
`ifdef RARELY_USED_SIGNALoutput wire [2:0]               PPROT       ,output wire                     PNSE        ,output wire [DATA_WIDTH/8-1:0]  PSTRB       ,output wire                     PWAKEUP     ,output wire [31:0]              PAUSER      ,output wire [DATA_WIDTH/2-1:0]  PWUSER      ,input  wire                     PSLVERR     ,input  wire [DATA_WIDTH/2-1:0]  PRUSER      ,input  wire [31:0]              PBUSER
`endif
);
localparam IDLE   = 2'b00;
localparam SETUP  = 2'b01;
localparam ACCESS = 2'b10;localparam BUSY   = 2'b01;
localparam NONSEQ = 2'b10;
localparam SEQ    = 2'b11;
/*********************************************************/
reg [ADDR_WIDTH-1:0] haddr_d;
reg                  hwrite_d;always @(posedge PCLK or negedge PRESETn) if(!PRESETn) #1 haddr_d  <= 32'd0; else #1 haddr_d  <= HADDR;
always @(posedge PCLK or negedge PRESETn) if(!PRESETn) #1 hwrite_d <=  1'b0; else #1 hwrite_d <= HWRITE;reg [ADDR_WIDTH-1:0] paddr_d;
reg                  pwrite_d;
reg [DATA_WIDTH-1:0] pwdata_d;always @(posedge PCLK or negedge PRESETn) if(!PRESETn) #1 paddr_d  <= 32'd0; else #1 paddr_d  <= PADDR;
always @(posedge PCLK or negedge PRESETn) if(!PRESETn) #1 pwrite_d <=  1'b0; else #1 pwrite_d <= PWRITE;
always @(posedge PCLK or negedge PRESETn) if(!PRESETn) #1 pwdata_d <= 32'd0; else #1 pwdata_d <= PWDATA;
/*********************************************************/
reg [1:0] state;
reg [1:0] nextstate;always @(*) begincase(state)IDLE:   if(HTRANS == NONSEQ && PREADYOUT && HSELx) nextstate = SETUP;else                                       nextstate = IDLE;SETUP:                                             nextstate = ACCESS;ACCESS: if(HTRANS == IDLE && PREADYOUT)            nextstate = IDLE;else                                       nextstate = ACCESS;default:                                           nextstate = IDLE;endcase
endalways @(posedge PCLK or negedge PRESETn) if(!PRESETn) #1 state <= IDLE; else #1 state <= nextstate;
/*********************************************************/
wire                  preadyin = ({PSEL2, PSEL1} == 2'b01) ? PREADYIN1 :({PSEL2, PSEL1} == 2'b10) ? PREADYIN2 : 1'b1;
wire [DATA_WIDTH-1:0] prdatain = ({PSEL2, PSEL1} == 2'b01) ? PRDATAIN1 :({PSEL2, PSEL1} == 2'b10) ? PRDATAIN2 : 32'd0;
/*********************************************************/
assign PADDR     = (state == SETUP)             ? haddr_d  : paddr_d;
assign PSEL1     = (state == IDLE)              ? 1'b0     :(PADDR[31:16] == 16'h0000)   ? 1'b1     : 1'b0;
assign PSEL2     = (state == IDLE)              ? 1'b0     :(PADDR[31:16] == 16'h0001)   ? 1'b1     : 1'b0;
assign PWRITE    = (state == SETUP)             ? hwrite_d : pwrite_d;
assign PWDATA    = (state == SETUP)             ? HWDATA   : pwdata_d;
assign PENABLE   = (state == ACCESS);
assign PREADYOUT = (state == IDLE)              ? 1'b1     :(state == SETUP)             ? 1'b0     : preadyin;
assign PRDATAOUT = (state == ACCESS && !PWRITE) ? prdatain : 32'd0;endmodule

1.3 Subordinate1

作为APB1总线的从机1,有3个等待周期

`timescale 1ns/1ps
module subordinate1 #(parameter DATA_WIDTH    = 32    ,parameter ADDR_WIDTH    = 32
)(input  wire                     PCLK        ,input  wire                     PRESETn     ,input  wire [ADDR_WIDTH-1:0]    PADDR       ,input  wire                     PSELx       ,input  wire                     PENABLE     ,input  wire                     PWRITE      ,input  wire [DATA_WIDTH-1:0]    PWDATA      ,output wire                     PREADYOUT   ,output wire [DATA_WIDTH-1:0]    PRDATAOUT
);
localparam IDLE   = 3'b000;
localparam STAGE1 = 3'b001;
localparam STAGE2 = 3'b010;
localparam STAGE3 = 3'b011;
localparam STAGE4 = 3'b100;reg [2:0] state;
reg [2:0] nextstate;always @(*) begincase(state) IDLE:   if(PSELx) nextstate = STAGE1;else      nextstate = IDLE; STAGE1:           nextstate = STAGE2;STAGE2:           nextstate = STAGE3;STAGE3:           nextstate = STAGE4;STAGE4:           nextstate = IDLE;default:          nextstate = IDLE;endcase
endalways @(posedge PCLK or negedge PRESETn) if(!PRESETn) #1 state <= IDLE; else #1 state <= nextstate;reg [DATA_WIDTH-1:0] reg0; //addr = 0
reg [DATA_WIDTH-1:0] reg1; //addr = 4
reg [DATA_WIDTH-1:0] reg2; //addr = 8
reg [DATA_WIDTH-1:0] reg3; //addr = c
reg [DATA_WIDTH-1:0] reg4; //addr = 10
reg [DATA_WIDTH-1:0] reg5; //addr = 14
reg [DATA_WIDTH-1:0] reg6; //addr = 18
reg [DATA_WIDTH-1:0] reg7; //addr = 1calways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg0 <= 32'd0;else if(state == STAGE4 && PWRITE && PADDR[15:0] == 16'h0)  #1 reg0 <= PWDATA;else                                                        #1 reg0 <= reg0;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg1 <= 32'd0;else if(state == STAGE4 && PWRITE && PADDR[15:0] == 16'h4)  #1 reg1 <= PWDATA;else                                                        #1 reg1 <= reg1;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg2 <= 32'd0;else if(state == STAGE4 && PWRITE && PADDR[15:0] == 16'h8)  #1 reg2 <= PWDATA;else                                                        #1 reg2 <= reg2;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg3 <= 32'd0;else if(state == STAGE4 && PWRITE && PADDR[15:0] == 16'hc)  #1 reg3 <= PWDATA;else                                                        #1 reg3 <= reg3;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg4 <= 32'd0;else if(state == STAGE4 && PWRITE && PADDR[15:0] == 16'h10) #1 reg4 <= PWDATA;else                                                        #1 reg4 <= reg4;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg5 <= 32'd0;else if(state == STAGE4 && PWRITE && PADDR[15:0] == 16'h14) #1 reg5 <= PWDATA;else                                                        #1 reg5 <= reg5;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg6 <= 32'd0;else if(state == STAGE4 && PWRITE && PADDR[15:0] == 16'h18) #1 reg6 <= PWDATA;else                                                        #1 reg6 <= reg6;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg7 <= 32'd0;else if(state == STAGE4 && PWRITE && PADDR[15:0] == 16'h1c) #1 reg7 <= PWDATA;else                                                        #1 reg7 <= reg7;
endassign PRDATAOUT = (state == STAGE4 && !PWRITE && PADDR[15:0] == 16'h0)  ? reg0 :(state == STAGE4 && !PWRITE && PADDR[15:0] == 16'h4)  ? reg1 :(state == STAGE4 && !PWRITE && PADDR[15:0] == 16'h8)  ? reg2 :(state == STAGE4 && !PWRITE && PADDR[15:0] == 16'hc)  ? reg3 :(state == STAGE4 && !PWRITE && PADDR[15:0] == 16'h10) ? reg4 :(state == STAGE4 && !PWRITE && PADDR[15:0] == 16'h14) ? reg5 :(state == STAGE4 && !PWRITE && PADDR[15:0] == 16'h18) ? reg6 :(state == STAGE4 && !PWRITE && PADDR[15:0] == 16'h1c) ? reg7 : 32'd0;assign PREADYOUT = (state == IDLE || state == STAGE4);endmodule

1.4 Subordinate2

作为APB1总线的从机2,无等待周期

`timescale 1ns/1ps
module subordinate2 #(parameter DATA_WIDTH    = 32    ,parameter ADDR_WIDTH    = 32
)(input  wire                     PCLK        ,input  wire                     PRESETn     ,input  wire [ADDR_WIDTH-1:0]    PADDR       ,input  wire                     PSELx       ,input  wire                     PENABLE     ,input  wire                     PWRITE      ,input  wire [DATA_WIDTH-1:0]    PWDATA      ,output wire                     PREADYOUT   ,output wire [DATA_WIDTH-1:0]    PRDATAOUT
);
localparam IDLE   = 3'b000;
localparam STAGE1 = 3'b001;reg [2:0] state;
reg [2:0] nextstate;always @(*) begincase(state) IDLE:   if(PSELx) nextstate = STAGE1;else      nextstate = IDLE;STAGE1:           nextstate = IDLE;default:          nextstate = IDLE;endcase
endalways @(posedge PCLK or negedge PRESETn) if(!PRESETn) #1 state <= IDLE; else #1 state <= nextstate;reg [DATA_WIDTH-1:0] reg0; //addr = 0
reg [DATA_WIDTH-1:0] reg1; //addr = 4
reg [DATA_WIDTH-1:0] reg2; //addr = 8
reg [DATA_WIDTH-1:0] reg3; //addr = c
reg [DATA_WIDTH-1:0] reg4; //addr = 10
reg [DATA_WIDTH-1:0] reg5; //addr = 14
reg [DATA_WIDTH-1:0] reg6; //addr = 18
reg [DATA_WIDTH-1:0] reg7; //addr = 1calways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg0 <= 32'd0;else if(state == STAGE1 && PWRITE && PADDR[15:0] == 16'h0)  #1 reg0 <= PWDATA;else                                                        #1 reg0 <= reg0;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg1 <= 32'd0;else if(state == STAGE1 && PWRITE && PADDR[15:0] == 16'h4)  #1 reg1 <= PWDATA;else                                                        #1 reg1 <= reg1;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg2 <= 32'd0;else if(state == STAGE1 && PWRITE && PADDR[15:0] == 16'h8)  #1 reg2 <= PWDATA;else                                                        #1 reg2 <= reg2;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg3 <= 32'd0;else if(state == STAGE1 && PWRITE && PADDR[15:0] == 16'hc)  #1 reg3 <= PWDATA;else                                                        #1 reg3 <= reg3;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg4 <= 32'd0;else if(state == STAGE1 && PWRITE && PADDR[15:0] == 16'h10) #1 reg4 <= PWDATA;else                                                        #1 reg4 <= reg4;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg5 <= 32'd0;else if(state == STAGE1 && PWRITE && PADDR[15:0] == 16'h14) #1 reg5 <= PWDATA;else                                                        #1 reg5 <= reg5;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg6 <= 32'd0;else if(state == STAGE1 && PWRITE && PADDR[15:0] == 16'h18) #1 reg6 <= PWDATA;else                                                        #1 reg6 <= reg6;
endalways @(posedge PCLK or negedge PRESETn) beginif(!PRESETn)                                                #1 reg7 <= 32'd0;else if(state == STAGE1 && PWRITE && PADDR[15:0] == 16'h1c) #1 reg7 <= PWDATA;else                                                        #1 reg7 <= reg7;
endassign PRDATAOUT = (state == STAGE1 && !PWRITE && PADDR[15:0] == 16'h0)  ? reg0 :(state == STAGE1 && !PWRITE && PADDR[15:0] == 16'h4)  ? reg1 :(state == STAGE1 && !PWRITE && PADDR[15:0] == 16'h8)  ? reg2 :(state == STAGE1 && !PWRITE && PADDR[15:0] == 16'hc)  ? reg3 :(state == STAGE1 && !PWRITE && PADDR[15:0] == 16'h10) ? reg4 :(state == STAGE1 && !PWRITE && PADDR[15:0] == 16'h14) ? reg5 :(state == STAGE1 && !PWRITE && PADDR[15:0] == 16'h18) ? reg6 :(state == STAGE1 && !PWRITE && PADDR[15:0] == 16'h1c) ? reg7 : 32'd0;assign PREADYOUT = (state == IDLE || state == STAGE1);endmodule

1.5 Decoder

`timescale 1ns/1ps
module decoder #(parameter ADDR_WIDTH    = 32
)(input  wire [ADDR_WIDTH-1:0]    HADDR   ,output wire                     HSEL1   ,output wire                     HSEL2   ,output wire                     HSELD 
);/** Address Space* ahb2apb1 0x0000_0000~0x0001_ffff 64KB* ahb2apb2 0x0002_0000~0x0003_ffff 64KB*/
reg hsel1;
reg hsel2;
reg hseld;always @(*) begincase(HADDR[31:16])16'h0000, 16'h0001:{hseld, hsel2, hsel1} = 3'b001;16'h0002, 16'h0003:{hseld, hsel2, hsel1} = 3'b010;default:{hseld, hsel2, hsel1} = 3'b100;endcase
endassign HSEL1 = hsel1;
assign HSEL2 = hsel2;
assign HSELD = hseld;endmodule

1.6 Testbench

`timescale 1ns/1ps
module testbench;localparam DATA_WIDTH   =   32;
localparam ADDR_WIDTH   =   32;
//size
localparam BYTE         =   3'd0;
localparam HALFWORD     =   3'd1;
localparam WORD         =   3'd2;
//burst
localparam SINGLE       =   3'd0;
localparam INCR         =   3'd1;
localparam WRAP4        =   3'd2;
localparam INCR4        =   3'd3;
localparam WRAP8        =   3'd4;
localparam INCR8        =   3'd5;
localparam WRAP16       =   3'd6;
localparam INCR16       =   3'd7;//ahb
reg                     HCLK        ;
reg                     HRESETn     ;
wire [ADDR_WIDTH-1:0]   HADDR       ;
wire [2:0]              HBURST      ;
wire [2:0]              HSIZE       ;
wire [1:0]              HTRANS      ;
wire [DATA_WIDTH-1:0]   HWDATA      ;
wire                    HWRITE      ;
reg                     cmd_start   ;
reg  [DATA_WIDTH-1:0]   cmd_wdata   ;
reg  [ADDR_WIDTH-1:0]   cmd_addr    ;
reg                     cmd_write   ;
reg  [2:0]              cmd_size    ;
reg  [2:0]              cmd_burst   ;
reg  [3:0]              cmd_length  ;
reg                     cmd_busy    ;
reg                     cmd_stop    ;
wire [DATA_WIDTH-1:0]   cmd_rdata   ;
wire                    cmd_error   ;
wire                    cmd_ready   ;
//decoder
wire                    HSEL1       ;
wire                    HSEL2       ;
//ahb2apb1
wire [ADDR_WIDTH-1:0]   PADDR       ;
wire                    PSEL1       ;
wire                    PSEL2       ;
wire                    PENABLE     ;
wire                    PWRITE      ;
wire [DATA_WIDTH-1:0]   PWDATA      ;
wire [DATA_WIDTH-1:0]   PRDATAOUT1  ;
wire                    PREADYOUT1  ;
//sub1
wire                    S_PREADYOUT1;
wire [DATA_WIDTH-1:0]   S_PRDATAOUT1;
//sub2
wire                    S_PREADYOUT2;
wire [DATA_WIDTH-1:0]   S_PRDATAOUT2;
//multiplexor
reg  [DATA_WIDTH-1:0]   HRDATA      ;
reg                     HREADY      ;
//rstn_sync
wire                    HRESETn_s   ;rstn_sync u_rstn_sync(.clk_i          (HCLK)          ,.rstn_async_i   (HRESETn)       ,.rstn_sync_o    (HRESETn_s)
);ahb #(.DATA_WIDTH     (DATA_WIDTH)    ,.ADDR_WIDTH     (ADDR_WIDTH)
)u_ahb(.HCLK           (HCLK)          ,.HRESETn        (HRESETn_s)     ,.HADDR          (HADDR)         ,.HBURST         (HBURST)        ,.HSIZE          (HSIZE)         ,.HTRANS         (HTRANS)        ,.HWDATA         (HWDATA)        ,.HWRITE         (HWRITE)        ,.HRDATA         (HRDATA)        ,.HREADY         (HREADY)        ,.HRESP          ()              ,.cmd_start      (cmd_start)     ,.cmd_wdata      (cmd_wdata)     ,.cmd_addr       (cmd_addr)      ,.cmd_write      (cmd_write)     ,.cmd_size       (cmd_size)      ,.cmd_burst      (cmd_burst)     ,.cmd_length     (cmd_length)    ,.cmd_busy       (cmd_busy)      ,.cmd_stop       (cmd_stop)      ,.cmd_rdata      (cmd_rdata)     ,.cmd_error      (cmd_error)     ,.cmd_ready      (cmd_ready)
);decoder #(.ADDR_WIDTH     (ADDR_WIDTH)    
)u_decoder(.HADDR          (HADDR)         ,.HSEL1          (HSEL1)         ,.HSEL2          (HSEL2)         ,.HSELD          ()
);ahb2apb1 #(.DATA_WIDTH     (DATA_WIDTH)    ,.ADDR_WIDTH     (ADDR_WIDTH)
)u_ahb2apb1(.PCLK           (HCLK)          ,.PRESETn        (HRESETn_s)     ,.PADDR          (PADDR)         ,.PSEL1          (PSEL1)         ,.PSEL2          (PSEL2)         ,.PENABLE        (PENABLE)       ,.PWRITE         (PWRITE)        ,.PWDATA         (PWDATA)        ,.PREADYIN1      (S_PREADYOUT1)  ,.PREADYIN2      (S_PREADYOUT2)  ,.PRDATAIN1      (S_PRDATAOUT1)  ,.PRDATAIN2      (S_PRDATAOUT2)  ,.HSELx          (HSEL1)         ,.HADDR          (HADDR)         ,.HTRANS         (HTRANS)        ,.HWRITE         (HWRITE)        ,.HSIZE          (HSIZE)         ,.HBURST         (HBURST)        ,.HWDATA         (HWDATA)        ,.PRDATAOUT      (PRDATAOUT1)    ,.PREADYOUT      (PREADYOUT1)
);subordinate1 #(.DATA_WIDTH     (DATA_WIDTH)    ,.ADDR_WIDTH     (ADDR_WIDTH)
)u_subordinate1(.PCLK           (HCLK)          ,.PRESETn        (HRESETn_s)     ,.PADDR          (PADDR)         ,.PSELx          (PSEL1)         ,.PENABLE        (PENABLE)       ,.PWRITE         (PWRITE)        ,.PWDATA         (PWDATA)        ,.PREADYOUT      (S_PREADYOUT1)  ,.PRDATAOUT      (S_PRDATAOUT1)
);subordinate2 #(.DATA_WIDTH     (DATA_WIDTH)    ,.ADDR_WIDTH     (ADDR_WIDTH)
)u_subordinate2(.PCLK           (HCLK)          ,.PRESETn        (HRESETn_s)     ,.PADDR          (PADDR)         ,.PSELx          (PSEL2)         ,.PENABLE        (PENABLE)       ,.PWRITE         (PWRITE)        ,.PWDATA         (PWDATA)        ,.PREADYOUT      (S_PREADYOUT2)  ,.PRDATAOUT      (S_PRDATAOUT2)
);multiplexor #(.DATA_WIDTH     (DATA_WIDTH)    
)u_multiplexor(.HCLK           (HCLK)          ,.HRESETn        (HRESETn_s)     ,.HSEL1          (HSEL1)         ,.HSEL2          (HSEL2)         ,.HSELD          ()              ,.HREADYIN1      (PREADYOUT1)    ,.HRDATAIN1      (PRDATAOUT1)    ,.HRESPIN1       ()              ,.HREADYIN2      ()              ,.HRDATAIN2      ()              ,.HRESPIN2       ()              ,.HREADYIND      ()              ,.HRDATAIND      ()              ,.HRESPIND       ()              ,.HRDATAOUT      (HRDATA)        ,.HREADYOUT      (HREADY)        ,.HRESPOUT       ()
);initial begin$fsdbDumpfile("ahb2apb.fsdb");$fsdbDumpvars(0, testbench);
endparameter TIMEOUT = 100000;always #10 HCLK = ~HCLK;initial beginHCLK        = 1'b0;HRESETn     = 1'b1;cmd_start   = 1'b0;cmd_wdata   =  'd0;cmd_addr    =  'd0;cmd_write   = 1'b0;cmd_size    = 3'd0;cmd_burst   = 3'd0;cmd_length  = 4'd0;cmd_stop    = 1'b0;cmd_busy    = 1'b0;#55 HRESETn = 1'b0;#50 HRESETn = 1'b1;fork begin#(TIMEOUT);$finish(2);end join_nonerepeat(10) @(posedge HCLK);Single_Write(32'h0000_0000, 32'd100);Single_Write(32'h0001_0000, 32'd200); Single_Read(32'h0000_0000);Single_Read(32'h0001_0000);//Single_Read(32'h0001_0000);/*case2(32'h0000_0000, 32'd0);case2(32'h0001_0000, 32'd0);case3(32'h0000_0000);case3(32'h0001_0000);*//*case4(32'h0000_001c, WRAP8);case5(32'h0000_0004, WRAP8);case4(32'h0001_0014, WRAP8);case5(32'h0001_0008, WRAP4);*/repeat(10) @(posedge HCLK);$finish;
endtask Single_Write(input [ADDR_WIDTH-1:0] addr, input [DATA_WIDTH-1:0] data); //Single write@(posedge HCLK) #1;cmd_start = 1'b1;@(posedge HCLK) #1;cmd_start = 1'b0;cmd_size  = WORD;cmd_burst = SINGLE;cmd_write = 1;cmd_addr  = addr;@(posedge HCLK) #1;cmd_wdata = data;cmd_size  = $urandom();cmd_burst = $urandom();cmd_write = $urandom();cmd_addr  = $urandom();@(posedge HCLK) #1;cmd_wdata = $urandom();#1 wait(HREADY);
endtasktask Single_Read(input [ADDR_WIDTH-1:0] addr); //Single read@(posedge HCLK) #1;cmd_start = 1'b1;@(posedge HCLK) #1;cmd_start = 1'b0;cmd_size  = WORD;cmd_burst = SINGLE;cmd_write = 0;cmd_addr  = addr;@(posedge HCLK) #1;cmd_wdata = $urandom();cmd_size  = $urandom();cmd_burst = $urandom();cmd_write = $urandom();cmd_addr  = $urandom();@(posedge HCLK) #1;#1 wait(HREADY);
endtasktask case2(input [ADDR_WIDTH-1:0] addr, input [DATA_WIDTH-1:0] data);//Incr write@(posedge HCLK) #1;cmd_start = 1'b1;@(posedge HCLK) #1;cmd_start = 1'b0;cmd_size  = WORD;cmd_burst = INCR;cmd_write = 1;cmd_addr  = addr;#1 wait(HREADY);                  //write reg0@(posedge HCLK) #1;cmd_wdata = $urandom(); #1 wait(HREADY);                  //write reg1@(posedge HCLK) #1;cmd_wdata = $urandom();#1 wait(HREADY);                  //write reg2@(posedge HCLK) #1;cmd_wdata = $urandom();#1 wait(HREADY);                  //write reg3@(posedge HCLK) #1;cmd_wdata = $urandom();#1 wait(HREADY);                  //write reg4@(posedge HCLK) #1;cmd_wdata = $urandom();#1 wait(HREADY);                  //write reg5@(posedge HCLK) #1;cmd_wdata = $urandom();#1 wait(HREADY);                  //write reg6@(posedge HCLK) #1;cmd_wdata = $urandom();#1 wait(HREADY); cmd_stop = 1'b1; //write reg7@(posedge HCLK) #1;cmd_stop = 1'b0;cmd_wdata = $urandom();#1 wait(HREADY);
endtasktask case3(input [ADDR_WIDTH-1:0] addr);//Incr read@(posedge HCLK) #1;cmd_start = 1'b1;@(posedge HCLK) #1;cmd_start = 1'b0;cmd_size  = WORD;cmd_burst = INCR;cmd_write = 0;cmd_addr  = addr;#1 wait(HREADY);                  //read reg0@(posedge HCLK) #1;#1 wait(HREADY);                  //read reg1@(posedge HCLK) #1;#1 wait(HREADY);                  //read reg2@(posedge HCLK) #1;#1 wait(HREADY);                  //read reg3@(posedge HCLK) #1;#1 wait(HREADY);                  //read reg4@(posedge HCLK) #1;#1 wait(HREADY);                  //read reg5@(posedge HCLK) #1;#1 wait(HREADY);                  //read reg6@(posedge HCLK) #1;#1 wait(HREADY); cmd_stop = 1'b1; //read reg7@(posedge HCLK) #1;cmd_stop = 1'b0;#1 wait(HREADY);
endtasktask case4(input [ADDR_WIDTH-1:0] addr, input [2:0] burst);//INCR4... write@(posedge HCLK) #1;cmd_start = 1'b1;@(posedge HCLK) #1;cmd_start = 1'b0;cmd_size  = WORD;cmd_burst = burst;cmd_write = 1;cmd_addr  = addr;case(cmd_burst)INCR4, WRAP4:repeat(4) begin#1 wait(HREADY);                  @(posedge HCLK) #1;cmd_wdata = $urandom(); endINCR8, WRAP8:repeat(8) begin#1 wait(HREADY);                  @(posedge HCLK) #1;cmd_wdata = $urandom(); endINCR16, WRAP16:repeat(16) begin#1 wait(HREADY);                  @(posedge HCLK) #1;cmd_wdata = $urandom(); endendcase#1 wait(HREADY);
endtasktask case5(input [ADDR_WIDTH-1:0] addr, input [2:0] burst);//INCR4... read@(posedge HCLK) #1;cmd_start = 1'b1;@(posedge HCLK) #1;cmd_start = 1'b0;cmd_size  = WORD;cmd_burst = burst;cmd_write = 0;cmd_addr  = addr;case(cmd_burst)INCR4, WRAP4:repeat(4) begin#1 wait(HREADY);                  @(posedge HCLK) #1;endINCR8, WRAP8:repeat(8) begin#1 wait(HREADY);                  @(posedge HCLK) #1;endINCR16, WRAP16:repeat(16) begin#1 wait(HREADY);                  @(posedge HCLK) #1;endendcase#1 wait(HREADY);
endtaskendmodule

二、仿真

2.1 Single Write和Single Read

image

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询