从其他几个模块内部访问一个模块的实例?(verilog) [英] Accessing instance of one module from inside of several other modules? (verilog)

查看:19
本文介绍了从其他几个模块内部访问一个模块的实例?(verilog)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个简单的系统,其中有一个内存模块(带有读写信号的简单 reg).现在这个内存必须被其他几个模块访问(不是同时).所以我创建了这个内存的一个实例并向它提供数据.但我不知道我的其他模块将如何访问内存模块的同一个实例.有什么帮助吗?

I am writing a simple system in which there is a memory module (simple reg with a read and write signals). Now this memory has to be accessed by several other modules (not simultaneously). So I create an instance of this memory and feed data to it. But I can't figure out how will my other modules access the same instance of the memory module. Any help?

编辑

让我通过一些代码来澄清一下.这是我的内存模块,简单的信号.

Let me clarify a bit by some code. This is my memory module, simple signals.

module rom(
    input [15:0] addr,
    input [15:0] data_in,
    input rd,
    input wr,
    input cs,
    output reg [15:0] data_out
    );

    reg [15:0] mem[255:0];
    integer k;
    initial begin
        for(k = 0;k<256;k=k+2)
            mem[k] = 16'h0011;
        for(k = 1;k<256;k=k+2)
            mem[k] = 16'h0101;
    end

    always @(cs)begin
        if(wr)
            mem[addr] <= data_in;
        if(rd)
            data_out <= mem[addr];
    end

endmodule

这将在我的顶层模块中实例化,就像这样

This will be instantiated in my top module, something like this

module Top;

    // Inputs
    reg [15:0] addr;
    reg [15:0] data_in;
    reg rd;
    reg wr;
    reg cs;

    // Outputs
    wire [15:0] data_out;

    // Instantiate the Unit Under Test (UUT)
    rom uut (
        .addr(addr), 
        .data_in(data_in), 
        .rd(rd), 
        .wr(wr), 
        .cs(cs), 
        .data_out(data_out)
    );
 ....
 ....
 ....
endmodule

现在这个顶层模块还将包含一些其他想要连接到内存的模块.我真的不明白我将如何连接它们.假设有一个这样的模块

Now this top module will also contain some other modules which would want to connect to memory. I don't really understand how I would connect them. Suppose there is one module like this

module IF_stage(
    input clk,
    input rst,
    output reg [15:0] pc,
    output [15:0] instruction
    );

    //pc control
    always@(posedge clk or posedge rst)
    begin
        if(rst)
            pc <= 16'hFFFF;
        else
            pc <= pc+1;
    end

 ....

我如何从这里访问内存模块?

How would I access the memory module from here?

推荐答案

首先,你的内存名称是rom",它是只读的.我认为这是一个错字,否则不需要有 wr 端口,您可以简单地在客户端中实现单独的 rom,并让合成器来优化设计.

First of all, the name of your memory is "rom", which is read only. I assume it is a typo, otherwise there is no need to have wr port and you can simply implement separate roms in clients and let synthesizer to optimize the design.

对于您的问题,基本上您需要一个仲裁器来处理多个客户端之间的争用.所有客户端都可以假设自己独占内存,但内存是所有客户端共享的,不能同时访问.

For your question, basically you need an arbiter to handle the contention between multiple clients. All clients can assume they occupy the memory exclusively but the memory is shared by all clients and cannot be accessed simultaneously.

蒂姆对 IF_stage 的看法是正确的.每个客户端必须有一个单独的内存接口

Tim is right about the IF_stage. Every client must have a separate memory interface

output [15:0] addr;
output [15:0] data_out;
input  [15:0] data_in;
output        wr, rd, cs;
input         rdy;          // only when rdy == 1, the memory operation is finished

您将需要一个内存控制器/仲裁器,它对所有客户端充当内存,但实际上处理客户端之间的争用.假设有三个客户端,并且所有客户端每三个周期访问内存的次数都少于一次,您可以简单地进行如下操作:

You will need a memory controller/arbiter, which behaves as a memory to all clients but actually handle the contention among clients. Assuming there are three clients and all clients access the memory less than once per three cycles, you can simply have something as follow:

module mem_ctl( 
                addr_c1, dw_c1, dr_c1, wr_c1, rd_c1, cs_c1,
                addr_c2, dw_c2, dr_c2, wr_c2, rd_c2, cs_c2,
                addr_c3, dw_c3, dr_c3, wr_c3, rd_c3, cs_c3,
                addr_m, dw_m, dr_m, wr_m, rd_m, cs_m, 
                rdy_c1, rdy_c2, rdy_c3,
                rst_n, clk
              );
input        clk, rst_n;
input [15:0] addr_c1, addr_c2, addr_c3, dw_c1, dw_c2, dw_c3;  // addr and data_write from clients
output [15:0] dr_c1, dr_c2, dr_c3;                         // data read from clients
input         wr_c1, wr_c2, wr_c3, rd_c1, rd_c2, rd_c3, cs_c1, cs_c2, cs_c3; // control from clients
output [15:0] addr_m, dw_m;                                // addr and data write to memory
input [15:0]  dr_m;
output        wr_m, rd_m, cs_m;                                   // control the memory
output        rdy_c1, rdy_c2, rdy_c3;

reg [15:0]    dr_c1, dr_c2, dr_c3, dw_m, addr_m;
reg           wr_m, rd_m, cs_m;

reg [1:0]     cnt;

always @(posedge clk or negedge rst_n)
  if (~rst_n)
    cnt <= 0;
  else if(cnt == 2'd2)
    cnt <= 0;
  else
    cnt <= cnt + 1;

always @(*)   // Verilog 2001, if not recognizable, fill in yourself
begin
  case(cnt)
  0: begin
     dw_m = dw_c1;
     wr_m = wr_c1;
     cs_m = cs_c1;
     rd_m = rd_c1;
     dr_c1 = dr_m;
  end
  1: begin
     dw_m = dw_c2;
     wr_m = wr_c2;
     cs_m = cs_c2;
     rd_m = rd_c2;
     dr_c2 = dr_m;
  end
  default: begin
     dw_m = dw_c3;
     wr_m = wr_c3;
     cs_m = cs_c3;
     rd_m = rd_c3;
     dr_c3 = dr_m;
  end
  endcase
end

assign rdy_c1 = (cnt == 0) & cs_c1;
assign rdy_c2 = (cnt == 1) & cs_c2;
assign rdy_c3 = (cnt == 2) & cs_c3;

endmodule

但是,这只有在所有客户端的访问速率低于每三个周期一次时才可以.如果访问速率是可变的并且高于该值,则您将需要在 mem_ctl 模块中使用真正的仲裁器.我认为循环仲裁就可以了.

However, this is only OK when the access rates of all clients are lower than once per three cycles. If the access rate is variant and higher than that, you will need a real arbiter in the mem_ctl module. I think a round-robin arbiter will be fine.

最后的评论,如果所有客户端的累计访问率大于每个周期一次,则无法在硬件中处理.在这种情况下,您需要通过其他方式来实现.

The final comment, if the accumulative access rates of all clients is larger than once per cycle, it is impossible to handle in hardware. In that case, you will need to do it in other ways.

这篇关于从其他几个模块内部访问一个模块的实例?(verilog)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆