verilog 设计与综合实验报告(7)

1、设计方案

首先定义一个缓存器,位宽为32位,深度为32位,然后根据读写时序,设置写使能和读使能wren = i_apb_pwrite && i_apb_penable && i_apb_psel; rden = ~i_apb_pwrite && ~i_apb_penable && i_apb_psel; 当写使能为高时,将数据写入缓存器,当读使能为高时,从缓存器中读取数据。

2、程序代码

module         APB_w_r#(
     parameter                   ADDR_WIDTH = 31,
    parameter                   DATA_WIDTH = 32
) (
    input                        clk                ,
   
    input                        i_apb_psel         ,
    input                        i_apb_pwrite       ,
    input                        i_apb_penable      ,
    
    input   [ADDR_WIDTH-1:0]     i_apb_paddr        ,
    input   [DATA_WIDTH-1:0]     i_apb_pwdata       ,
      
    output  [DATA_WIDTH-1:0]     o_apb_prdata                               
    );
 wire wren,rden;
 reg [31:0] mem[31:0]; //定义一个位宽32位,深度32的memery
 wire [31:0]addr;
 reg [DATA_WIDTH-1:0]prdata;
 assign o_apb_prdata = prdata;
 assign wren = i_apb_pwrite && i_apb_penable && i_apb_psel; 
 assign rden = ~i_apb_pwrite && ~i_apb_penable && i_apb_psel; 

 assign addr = i_apb_paddr;   
 always @(posedge clk)
    begin
        if (wren)
            mem[addr] <= i_apb_pwdata;
        else 
            mem[addr] <= mem[addr] ;
    end
 always @(posedge clk)
    begin
        if (rden)
            prdata <= mem[addr];
        else
            prdata <= 'h0;
End
Endmodule

3、仿真测试

module APB_w_r_tb;
reg clk                  ;

reg i_apb_psel           ;
reg i_apb_pwrite         ;
reg i_apb_penable        ;

reg [31:0]i_apb_paddr    ;
reg [31:0]i_apb_pwdata   ;

wire [31:0]o_apb_prdata  ;


always #5 clk = ~clk;
initial begin
    $stop            ;
    clk           = 0;
    i_apb_psel    = 0;
    i_apb_pwrite  = 0;
    i_apb_penable = 0;
    i_apb_paddr   = 0;
    i_apb_pwdata  = 0;
    #10
    w_data('d1,'d2)  ;
    r_data('d1)      ;
    w_data('d2,'d3)  ;
    r_data('d2)      ;
end
APB_w_r#(
    .ADDR_WIDTH('d2),
    .DATA_WIDTH('d32)
) APB_w_r(
    .clk           (clk)                 ,
    .i_apb_psel    (i_apb_psel)          ,
    .i_apb_pwrite  (i_apb_pwrite)        ,
    .i_apb_penable (i_apb_penable)       ,
                 
    .i_apb_paddr   (i_apb_paddr)         ,
    .i_apb_pwdata  (i_apb_pwdata)        ,
 
    .o_apb_prdata  (o_apb_prdata)                             
    );

task w_data(
    input  [31:0]w_addr,
    input [31:0]w_wdata
);begin
    @(posedge clk)
    i_apb_psel = 'd1;
    i_apb_pwrite = 'd1;
    i_apb_penable ='d0;
    i_apb_paddr = w_addr;
    i_apb_pwdata = w_wdata;
    @(posedge clk)
    i_apb_psel = 'd1;
    i_apb_pwrite = 'd1;
    i_apb_penable = 'd1;
    @(posedge clk)
    i_apb_penable = 'd0;
    i_apb_psel = 'd0;
    //i_apb_pwdata = 'd0;
    
end
endtask

task r_data(
    input  [31:0]r_addr
//    output [31:0]r_wdata
);

begin
    //assign r_wdata =o_apb_prdata;
    @(posedge clk)
    i_apb_psel = 'd1;
    i_apb_pwrite = 'd0;
    i_apb_penable ='d0;
    i_apb_paddr = r_addr;  
    //r_wdata = o_apb_prdata;
    @(posedge clk)
    i_apb_psel = 'd1;
    i_apb_pwrite = 'd0;
    i_apb_penable = 'd1;
    //r_wdata = o_apb_prdata;
    @(posedge clk)
    i_apb_penable = 'd0;
    i_apb_psel = 'd0;
    
end
endtask
endmodule

4、结果分析

当i_apb_psel为高,i_apb_penable为低,i_apb_pwrite为高时写入数据2和地址1,之后i_apb_penable为高时保持一个周期,之后读时序i_apb_psel为高,i_apb_penable为低,i_apb_pwrite为低时,地址1,读出数据2。进行下一次写入地址2数据3,读出数据3。

  • 17
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积极向@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值