一、代码
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
