Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 65 additions & 36 deletions src/synth_fpga.cc
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ struct SynthFpgaPass : public ScriptPass {
//
pool<string> dff_features;
dict<string, string> dff_models;

string dff_techmap;
vector<string> legal_flops;

Expand Down Expand Up @@ -499,10 +500,6 @@ struct SynthFpgaPass : public ScriptPass {

log(" ====================================================================="
"=====\n");

// Wait a bit to see the config file data on the screen
//
usleep(5000000);
}

// -------------------------
Expand Down Expand Up @@ -539,9 +536,7 @@ struct SynthFpgaPass : public ScriptPass {
for (auto it : G_config.dff_features) {
ys_dff_features.insert(it);
}
for (auto it : G_config.dff_models) {
ys_dff_models[it.first] = it.second;
}

for (auto it : G_config.legal_flops) {
ys_legal_flops.push_back(it);
}
Expand Down Expand Up @@ -923,8 +918,8 @@ struct SynthFpgaPass : public ScriptPass {
log_error("'partname' is missing in config file '%s'.\n",
config_file.c_str());
}
JsonNode *partname = root.data_dict.at("partname");
if (partname->type != 'S') {
JsonNode *partname_node = root.data_dict.at("partname");
if (partname_node->type != 'S') {
log_error("'partname' must be a string.\n");
}

Expand Down Expand Up @@ -990,7 +985,8 @@ struct SynthFpgaPass : public ScriptPass {
G_config.root_path = root_path->data_string;
}

G_config.partname = partname->data_string;
G_config.partname = partname_node->data_string;
// part_name = G_config.partname;

G_config.lut_size = lut_size->data_number;

Expand Down Expand Up @@ -1034,9 +1030,10 @@ struct SynthFpgaPass : public ScriptPass {
log_error("'models' from 'flipflops' is missing in config file '%s'.\n",
config_file.c_str());
}

JsonNode *dff_models = flipflops->data_dict.at("models");
if (dff_models->type != 'D') {
log_error("'models' associated to 'flipflops' must be a dictionary.\n");
log_warning("'models' associated to 'flipflops' must be a dictionary to be read in. Ignoring contents.\n");
}

for (auto it : dff_models->data_dict) {
Expand All @@ -1048,6 +1045,7 @@ struct SynthFpgaPass : public ScriptPass {
dff_model_str.c_str());
}
G_config.dff_models[dff_model_str] = dff_model_path->data_string;
log_warning("Not reading dff_models from the flipflops 'models' entry. Please use 'techmap'.\n");
}

if (flipflops->data_dict.count("legalize_list") == 0) {
Expand Down Expand Up @@ -2359,10 +2357,10 @@ struct SynthFpgaPass : public ScriptPass {
}

// -------------------------
// load_cells_models
// load_hardcoded_cell_models
// -------------------------
//
void load_cells_models() {
void load_hardcoded_cell_models() {
run("read_verilog +/plugins/wildebeest/ff_models/dffer.v");
run("read_verilog +/plugins/wildebeest/ff_models/dffes.v");
run("read_verilog +/plugins/wildebeest/ff_models/dffe.v");
Expand All @@ -2383,29 +2381,50 @@ struct SynthFpgaPass : public ScriptPass {
}
}

void load_cell_models_from_config() {

// Deprecate this path magic in a future version.

std::filesystem::path config_path(G_config.config_file);

// Get the parent cad directory path
std::filesystem::path cad_directory = config_path.parent_path();

log("Loading cell models from config\n");

if(G_config.dff_techmap != "") {
std::filesystem::path dff_techmap_path(G_config.dff_techmap);
if(dff_techmap_path.is_absolute()) {
dff_techmap_path = cad_directory / dff_techmap_path.relative_path();
log_warning("dff techmap file path '%s' is absolute, but treating as relative to config file directory.\n", G_config.dff_techmap.c_str()); // Path is expected to be relative, in same dir as .*config.json
}
else {
dff_techmap_path = cad_directory / dff_techmap_path;
}
log("Reading dff techmap from %s\n", dff_techmap_path.string().c_str());
run("read_verilog " + dff_techmap_path.string());
}

if(G_config.dsps_techmap != ""){
std::filesystem::path dsp_techmap_path(G_config.dsps_techmap);
if(dsp_techmap_path.is_absolute()) {
dsp_techmap_path = cad_directory / dsp_techmap_path.relative_path();
log_warning("dsp techmap file path '%s' is absolute, but treating as relative to config file directory.\n", G_config.dsps_techmap.c_str()); // Path is expected to be relative, in same dir as .*config.json
}
else {
dsp_techmap_path = cad_directory / dsp_techmap_path;
}
log("Reading dsp techmap from %s\n", dsp_techmap_path.string().c_str());
run("read_verilog " + dsp_techmap_path.string());
}
}

// -------------------------
// load_bb_cells_models
// -------------------------
//
void load_bb_cells_models() {
run("read_verilog +/plugins/wildebeest/ff_models/dffer.v");
run("read_verilog +/plugins/wildebeest/ff_models/dffes.v");
run("read_verilog +/plugins/wildebeest/ff_models/dffe.v");
run("read_verilog +/plugins/wildebeest/ff_models/dffr.v");
run("read_verilog +/plugins/wildebeest/ff_models/dffs.v");
run("read_verilog +/plugins/wildebeest/ff_models/dff.v");

run("read_verilog +/plugins/wildebeest/ff_models/dffh.v");
run("read_verilog +/plugins/wildebeest/ff_models/dffeh.v");
run("read_verilog +/plugins/wildebeest/ff_models/dffl.v");
run("read_verilog +/plugins/wildebeest/ff_models/dffel.v");
run("read_verilog +/plugins/wildebeest/ff_models/dffhl.v");
run("read_verilog +/plugins/wildebeest/ff_models/dffehl.v");

if (part_name == "z1010") {
run("read_verilog "
"+/plugins/wildebeest/architecture/z1010/models/tech_mae.v");
}
load_hardcoded_cell_models();

// Black box them all
//
Expand Down Expand Up @@ -2726,8 +2745,6 @@ struct SynthFpgaPass : public ScriptPass {

run("stat");

// We may need to parametrize this in the config file with a new section
//
if (has_cell_type(yosys_get_design(), "\\MAE")) {
log_error("Could not techmap DSP to a valid configuration.\n");
}
Expand Down Expand Up @@ -3318,11 +3335,18 @@ struct SynthFpgaPass : public ScriptPass {
//
run(stringf("hierarchy %s", help_mode ? "-top <top>" : top_opt.c_str()));

// This is usefull to load non-lut cells models in case we are doing a
// This is useful to load non-lut cells models in case we are doing a
// resynthesis, e.g when the input design is a previous synthesized
// netlist which has been synthesized with 'synth_fpga'.
//
load_cells_models();

if(config_file == "") {
load_hardcoded_cell_models();
}
else {
load_cell_models_from_config();
}


// In case user invokes the '-resynthesis' option at the command line level,
// we perform a light weight synthesis for the second time.
Expand Down Expand Up @@ -3565,7 +3589,12 @@ struct SynthFpgaPass : public ScriptPass {

float totalTime = 1 + elapsed.count() * 1e-9;

log(" PartName : %s\n", part_name.c_str());
if(config_file == ""){
log(" PartName : %s\n", part_name.c_str());
}
else {
log(" PartName : %s\n", G_config.partname.c_str());
}
log(" DSP Style : %s\n", dsp_tech.c_str());
log(" BRAM Style : %s\n", bram_tech.c_str());
log(" OPT target : %s\n", opt.c_str());
Expand Down
8 changes: 6 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@

set(ALL_TESTS
unit/check_commands.ys
unit/heartbeat-z1000.ys
unit/heartbeat-z1010.ys
unit/heartbeat-z1000-config.ys
unit/heartbeat-z1010-config.ys
unit/heartbeat-z1000-hardcode.ys
unit/heartbeat-z1010-hardcode.ys
unit/heartbeat-z1000-config-abspath.ys
unit/heartbeat-z1010-config-abspath.ys
)

foreach(test_script ${ALL_TESTS})
Expand Down
21 changes: 11 additions & 10 deletions tests/unit/data/z1000/z1000.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
"partname": "z1000",
"lut_size": 4,
"flipflops": {
"features": ["async_reset", "async_set", "flop_enable"],
"features": [
"async_reset",
"flop_enable"
],
"models": {
"dffers": "/ffs/dffers.v",
"dffer": "/ffs/dffer.v",
"dffes": "/ffs/dffes.v",
"dffe": "/ffs/dffe.v",
"dffrs": "/ffs/dffrs.v",
"dffr": "/ffs/dffr.v",
"dffs": "/ffs/dffs.v",
"dff": "/ffs/dff.v"
},
"techmap": "/tech_flops.v"
"legalize_list": [
"$_DFF_PN0_",
"$_DFF_P_",
"$_DFFE_PP_",
"$_DFFE_PN0P_"
],
"techmap": "tech_flops.v"
}
}
20 changes: 20 additions & 0 deletions tests/unit/data/z1000/z1000_abspath.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"version": 1,
"partname": "z1000",
"lut_size": 4,
"flipflops": {
"features": [
"async_reset",
"flop_enable"
],
"models": {
},
"legalize_list": [
"$_DFF_PN0_",
"$_DFF_P_",
"$_DFFE_PP_",
"$_DFFE_PN0P_"
],
"techmap": "/tech_flops.v"
}
}
19 changes: 6 additions & 13 deletions tests/unit/data/z1010/z1010.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,18 @@
"lut_size": 4,
"flipflops": {
"features": ["async_reset", "async_set", "flop_enable"],
"models": {
"dffers": "/ffs/dffers.v",
"dffer": "/ffs/dffer.v",
"dffes": "/ffs/dffes.v",
"dffe": "/ffs/dffe.v",
"dffrs": "/ffs/dffrs.v",
"dffr": "/ffs/dffr.v",
"dffs": "/ffs/dffs.v",
"dff": "/ffs/dff.v"
"models": {
},
"techmap": "/tech_flops.v"
"legalize_list": ["$_DFF_PN0_", "$_DFF_P_", "$_DFFE_PP_", "$_DFFE_PN0P_"],
"techmap": "tech_flops.v"
},
"brams": {
"memory_libmap": ["/bram_memory_map.txt"]
"techmap": ["/tech_bram.v"]
"memory_libmap": ["/bram_memory_map.txt"],
"techmap": ["tech_bram.v"]
},
"dsps": {
"family": "DSP48",
"techmap": "/mult18x18_DSP48.v",
"techmap": "mult18x18_DSP48.v",
"techmap_parameters": {
"DSP_A_MAXWIDTH": 18,
"DSP_B_MAXWIDTH": 18,
Expand Down
29 changes: 29 additions & 0 deletions tests/unit/data/z1010/z1010_abspath.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"version": 1,
"partname": "z1010",
"lut_size": 4,
"flipflops": {
"features": ["async_reset", "async_set", "flop_enable"],
"models": {
},
Comment on lines +7 to +8
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably makes sense to have a test that includes the models to ensure this behavior is properly implemented at this time.

"legalize_list": ["$_DFF_PN0_", "$_DFF_P_", "$_DFFE_PP_", "$_DFFE_PN0P_"],
"techmap": "/tech_flops.v"
},
"brams": {
"memory_libmap": ["/bram_memory_map.txt"],
"techmap": ["/tech_bram.v"]
},
"dsps": {
"family": "DSP48",
"techmap": "/mult18x18_DSP48.v",
"techmap_parameters": {
"DSP_A_MAXWIDTH": 18,
"DSP_B_MAXWIDTH": 18,
"DSP_A_MINWIDTH": 2,
"DSP_B_MINWIDTH": 2,
"DSP_Y_MINWIDTH": 9,
"DSP_SIGNEDONLY": 1,
"DSP_NAME": "$__MUL18X18"
}
}
}
30 changes: 30 additions & 0 deletions tests/unit/heartbeat-z1000-config-abspath.ys
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# yosys -m wildebeest -s heartbeat-z1000-config-abspath.ys
read_verilog <<EOF
module heartbeat #(
parameter N = 8
) (
//inputs
input clk, // clock
input nreset, //async active low reset
//outputs
output reg out //heartbeat
);

reg [N-1:0] counter_reg;

always @(posedge clk or negedge nreset) begin
if (!nreset) begin
counter_reg <= {(N) {1'b0}};
out <= 1'b0;
end else begin
counter_reg <= counter_reg + 1'b1;
out <= (counter_reg == {(N) {1'b1}});
end
end

endmodule
EOF

synth_fpga -config data/z1000/z1000_abspath.json -show_config
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same about log assertions

select -assert-count 9 */t:dffr
select -assert-count 11 */t:$lut
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# yosys -m wildebeest -s heartbeat-z1000-config.ys
read_verilog <<EOF
module heartbeat #(
parameter N = 8
Expand Down
30 changes: 30 additions & 0 deletions tests/unit/heartbeat-z1000-hardcode.ys
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# yosys -m wildebeest -s heartbeat-z1000-hardcode.ys
read_verilog <<EOF
module heartbeat #(
parameter N = 8
) (
//inputs
input clk, // clock
input nreset, //async active low reset
//outputs
output reg out //heartbeat
);

reg [N-1:0] counter_reg;

always @(posedge clk or negedge nreset) begin
if (!nreset) begin
counter_reg <= {(N) {1'b0}};
out <= 1'b0;
end else begin
counter_reg <= counter_reg + 1'b1;
out <= (counter_reg == {(N) {1'b1}});
end
end

endmodule
EOF

synth_fpga -partname z1000
select -assert-count 9 */t:dffr
select -assert-count 11 */t:$lut
Loading