YosysHQ / yosys

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

some question about BRAM #3221

Closed kangliyu1 closed 1 month ago

kangliyu1 commented 2 years ago

Hello! When I used script 1 to synthesize the code1 below, I found that the circuit occupied too many resources. After thinking, I found that the initail part caused too much resource occupancy. How should I deal with this problem?Can the BRAM in it use a file like coe or other methods to pre-store the data initialized in initail into the BRAM? I hope you can give some pointers. The comprehensive results are shown in Figure 1:

code1:


module database(clk,datata,re,address,we,dp,address_p);
parameter SIZE=11;
input clk;
output reg signed [SIZE-1:0] datata;
input re,we;
input [12:0] address;
input signed [SIZE-1:0] dp;
input [12:0] address_p;
reg signed [SIZE-1:0] storage [5459:0];

initial begin
storage[0] =  11'b0;
storage[1] =  11'b0;
storage[2] =  11'b0;
storage[3] =  11'b0;
storage[4] =  11'b0;
........
.......,
........
storage[5454] =  11'b00001110010; // 114
storage[5455] = -11'b01010000110; // -646
storage[5456] =  11'b00000100011; // 35
storage[5457] = -11'b00010100101; // -165
storage[5458] =  11'b01010101000; // 680
storage[5459] = -11'b00010001101; // -141
end

always @(posedge clk) if (we==1) storage[address_p] <= dp;
always @(posedge clk) if (re==1) datata<=storage[address];

endmodule

script 1:


# Yosys synthesis script for ${TOP_MODULE}

#########################
# Parse input files
#########################
# Read verilog files
${READ_VERILOG_FILE}
# Read technology library
read_verilog -lib -specify ${YOSYS_CELL_SIM_VERILOG}

#########################
# Prepare for synthesis
#########################
# Identify top module from hierarchy
hierarchy -check -top ${TOP_MODULE}
# - Convert process blocks to AST
proc
# Flatten all the gates/primitives
flatten
# Identify tri-state buffers from 'z' signal in AST
# with follow-up optimizations to clean up AST
tribuf -logic
opt_expr
opt_clean
# demote inout ports to input or output port
# with follow-up optimizations to clean up AST
deminout
opt

opt_expr
opt_clean
check
opt
wreduce -keepdc
peepopt
pmuxtree
opt_clean

########################
# Map multipliers
# Inspired from synth_xilinx.cc
#########################
# Avoid merging any registers into DSP, reserve memory port registers first
memory_dff
wreduce t:$mul
techmap -map +/mul2dsp.v -map ${YOSYS_DSP_MAP_VERILOG} ${YOSYS_DSP_MAP_PARAMETERS}
select a:mul2dsp
setattr -unset mul2dsp
opt_expr -fine
wreduce
select -clear
chtype -set $mul t:$__soft_mul# Extract arithmetic functions

#########################
# Run coarse synthesis
#########################
# Run a tech map with default library
techmap
alumacc
share
opt
fsm
# Run a quick follow-up optimization to sweep out unused nets/signals
opt -fast
# Optimize any memory cells by merging share-able ports and collecting all the ports belonging to memorcy cells  
memory -nomap
opt_clean

#########################
# Map logics to BRAMs
#########################
memory_bram -rules ${YOSYS_BRAM_MAP_RULES}
techmap -map ${YOSYS_BRAM_MAP_VERILOG}
opt -fast -mux_undef -undriven -fine
memory_map
opt -undriven -fine

#########################
# Map flip-flops
#########################
techmap -map ${YOSYS_DFF_MAP_VERILOG}
opt_expr -mux_undef
simplemap
opt_expr
opt_merge
opt_rmdff
opt_clean
opt

#########################
# Map LUTs
#########################
abc -lut ${LUT_SIZE}

#########################
# Check and show statisitics
#########################
hierarchy -check
stat

#########################
# Output netlists
#########################
opt_clean -purge
write_blif ${OUTPUT_BLIF}

fig1: image

Lunaphied commented 2 years ago

You could reduce the number of lines of code in the initial block by using something like $readmemb or $readmemh to initialize the contents from a separate file. But this will only improve code cleanliness, it should not affect the resulting synthesis.

For your question on reducing the resource usage, this is harder to say. You're doing custom synthesis which has resulted in mapping ultimately to $_DFF_P_ which is a Yosys internal cell that will usually get mapped by a liberty file onto a technology specific primitive. You are not actually mapping to a BRAM. I am not sure if this was your intent, but there's not enough information in the output from Yosys you provided to fully understand what happens when this gets run.

For what it's worth, I would check to see what things are looking like right before the memory_map step runs. Since that pass will convert any memories not mapped already by the techmap pass above into DFF based memories that eventually get mapped to the $_DFF_P_ internal primitives you see in your results.

povik commented 1 month ago

Closing as stale. @kangliyu1 If you still want the original questions answered please reopen the issue or, preferably, open a discussion thread.