YosysHQ / yosys

Yosys Open SYnthesis Suite
https://yosyshq.net/yosys/
ISC License
3.44k stars 878 forks source link

Yosys could not make use of the read_en signal #3740

Open narutozxp opened 1 year ago

narutozxp commented 1 year ago

Version

Yosys 0.28+4 (git sha1 7efc50367, clang 14.0.0-1ubuntu1 -fPIC -Os)

On which OS did this happen?

Linux

Reproduction Steps

module sync_dual_port_ram_1 #( 
    parameter   ADDRESS_WIDTH   =   4, 
    parameter   DATA_WIDTH      =   8  
)(
    input                               clk             ,                                            
    input                               write_en        ,
    input                               read_en         ,                               
    input       [ADDRESS_WIDTH-1:0]     read_address    , 
    input       [ADDRESS_WIDTH-1:0]     write_address   , 
    input       [DATA_WIDTH-1   :0]     write_data_in   ,                  
    output reg       [DATA_WIDTH-1   :0]     read_data_out  
);

    reg     [DATA_WIDTH-1   :0]         ram [2**ADDRESS_WIDTH-1:0];              

    always @(posedge clk) begin
        if (write_en) begin                          
            ram[write_address]  <=  write_data_in; 
        end
        else if (read_en) begin
            read_data_out    <=  ram[read_address];
        end
    end

endmodule

module sync_dual_port_ram_2 #( 
    parameter   ADDRESS_WIDTH   =   4, 
    parameter   DATA_WIDTH      =   8  
)(
    input                               clk             ,                                            
    input                               write_en        ,
  input                               read_en         ,                               
    input       [ADDRESS_WIDTH-1:0]     read_address    , 
  input       [ADDRESS_WIDTH-1:0]     write_address   , 
    input       [DATA_WIDTH-1   :0]     write_data_in   ,                  
    output reg       [DATA_WIDTH-1   :0]     read_data_out  
);

    reg     [DATA_WIDTH-1   :0]         ram [2**ADDRESS_WIDTH-1:0];              

    always @(posedge clk) begin
        if (write_en) begin                          
            ram[write_address]  <=  write_data_in; 
    end
            read_data_out    <=  ram[read_address];
    end

endmodule

The following is the content of my mapping rules file

bram $__MY_DPRAM_1024x8
  init 0
  abits 10
  dbits 8
  groups 2
  ports  1  1
  wrmode 1  0
  enable 1  1
  transp 0  0
  clocks 1  1
  clkpol 1  1
endbram

match $__MY_DPRAM_1024x8
  min efficiency 0
  make_transp
endmatch

The following is the file used by techmap pass

module $__MY_DPRAM_1024x8 (
  output [0:7] B1DATA,
  input CLK1,
  input [0:9] B1ADDR,
  input [0:9] A1ADDR,
  input [0:7] A1DATA,
  input A1EN,
  input B1EN );

  generate
    dpram_1024x8 #() _TECHMAP_REPLACE_ (
      .clk    (CLK1),
      .wen    (A1EN),
      .waddr    (A1ADDR),
      .data_in    (A1DATA),
      .ren    (B1EN),
      .raddr    (B1ADDR),
      .data_out    (B1DATA) );
  endgenerate

endmodule

the bram synthesis flows are as follows:

memory_bram -rules ./bram.txt

techmap -map ./bram_map.v
opt -fast -mux_undef -undriven -fine -nodffe -nosdff
memory_map
opt -undriven -fine -nodffe -nosdff

the first module is synthesized into a group of ffs , however, the second one is synthesized into my aimed block ram with the constant 1 at the ren pin. It seems that the yosys can't make use of the "read_en" signal。

Expected Behavior

the first module should be synthesized into my aimed dpram with the ren controlled by read_en

Actual Behavior

the first module is synthesized into a group of ffs

nakengelhardt commented 1 year ago

Note: memory_bram is deprecated, we recommend using memory_libmap instead.

Please post the full script; is uses the en signal when I try: sync_dual_port_ram_1

This is the result from the following script:

read_verilog top.v

proc
hierarchy -top sync_dual_port_ram_1

flatten
opt_expr
opt_clean
check
opt
wreduce
peepopt
opt_clean
share
opt_expr
opt_clean
memory -nomap
opt_clean
memory_bram -rules ./bram.txt
techmap -map ./bram_map.v
opt -fast -mux_undef -undriven -fine -nodffe -nosdff
memory_map
opt -undriven -fine -nodffe -nosdff
show
narutozxp commented 1 year ago

I think the reason why I got a suboptimal result is that I used the command “opt -nodffe -nosdff” instead of “opt”, but I don’t understand why this command would cause such an outcome.