【问题标题】:How to write to inout port and read from inout port of the same module?如何写入inout端口并从同一模块的inout端口读取?
【发布时间】:2023-03-29 01:47:01
【问题描述】:

这并不是要实际创建一个带有输入输出端口的 verilog 模块。我发现了很多关于这方面的帖子。

我坚持的是,如果我有一个带有输入端口的黑盒模块,假设它的定义类似于

module blackbox(inout a, in b, in c)

我想在不同的模块中实例化它,比如

module myModule(input reg inReg, output wire outWire) blackbox(outWire);

如何使用 inReg 驱动黑盒并在不同时间将其输出到 outWire?我不知道如何连接一个和断开另一个。这显然过于简单化了。我真正拥有的是下面,但它更复杂。

module sram_control(
    input wire HCLK,
    input wire [20:0] HADDR,
    input wire HWRITE,
    input wire [1:0] HTRANS,
    input wire [7:0] HWDATA,
    output reg [7:0] HRDATA
    );
parameter IDLE_PHASE = 2'b00;
parameter WRITE_PHASE = 2'b01;
parameter READ_PHASE = 2'b10;

parameter IDLE = 2'b00;
parameter NONSEQ = 2'b10;

parameter READ = 1'b0;
parameter WRITE = 1'b1;

reg current_state, next_state;

wire CE, WE, OE;
reg [20:0] A;
wire [7:0] DQ;
reg [7:0] DQ_tmp1;
wire [7:0] DQ_tmp2;

async the_mem(.CE_b(CE), .WE_b(WE), .OE_b(OE), .A(A), .DQ(DQ));

always @(posedge HCLK) begin
  if(current_state == IDLE_PHASE) begin
        next_state <= HTRANS == NONSEQ? (HWRITE == WRITE? WRITE_PHASE : READ_PHASE) : IDLE_PHASE;   
         A <= HADDR;
  end
    else if(current_state != IDLE_PHASE) begin
        if(HTRANS == NONSEQ) begin
          if(HWRITE == WRITE) begin
            next_state <= WRITE_PHASE;
          end
          else begin 
            next_state <= READ_PHASE;
          end
        end
        else next_state <= IDLE_PHASE;
    end
    // we never get here
    else next_state <= IDLE_PHASE;
end

always@(posedge HCLK) begin
  if(current_state == READ_PHASE) HRDATA <= DQ;
end

assign CE = current_state != IDLE_PHASE? 1 : 0;
assign WE = current_state != IDLE && HWRITE == WRITE? 1 : 0;
assign OE = current_state != IDLE_PHASE? 1 : 0;
always@(posedge HCLK) current_state <= next_state;
endmodule

当我想写入异步模块时,我需要一种将 HWDATA 分配给异步模块的方法,而当我想从异步中读取时,我需要一种将异步模块的输出分配给 HRDATA 的方法。

【问题讨论】:

    标签: verilog inout


    【解决方案1】:

    对于所有inout 端口,您可以随时读取数据。但是为了驱动该网络,通常使用三态缓冲器。原因是同一个网络可能被多个模块共享,由于网络是inout类型,为了消除多个驱动程序的冲突,使用三态缓冲区。

    对于上图,代码如下。

    assign io = t ? i : 1'bz; // To drive the inout net
    assign o = io; // To read from inout net
    

    【讨论】:

      【解决方案2】:

      正如您所说,这不是 Verilog 问题,而是逻辑设计问题。

      你需要实现一个三态驱动来驱动DQ

      assign DQ = WE ? 8'bz : HWDATA;
      

      (假设你在写的时候WE1'b0)。

      一般来说,我会避免在 IC/FPGA 内部使用三态逻辑,因为不仅有多个驱动器驱动总线时会出现明显问题,如果没有驱动器也会出现问题总线(一些门得到浮动输入)。 IC设计还存在进一步的问题。但是,在这种情况下,您可能别无选择;大概你没有设计模块async。 (如果你这样做了 - 取出 inout。)

      【讨论】:

      • 事实证明,我已经解决了这个问题,并认为这是我的问题,但事实并非如此。但是,感谢大家向我展示了我实际上是在寻找错误的区域来解决我认为的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多