Comments (6)
There is a couple of things going on here.
First the Yosys Verilog parser did not support functions returning "integer". This is fixed now.
Second, the Yosys Verilog frontend does yet not support constant evaluation of functions for parameters. This is a bit tricky to add. I will look into it later and write another comment regarding this issue then. So this is why it sill fails case with ICARUS not set.
Regarding the case with ICARUS set: This would generally work with Yosys (the $clog2 function is supported). But this module is not synthesizable with this default parameters. With PRECISION=32 this module tries to access bits 4:0 of in2, but in2 is only 1 bit wide. This also creates an error when trying to synthesize the module with Xilinx XST, for example.
When you define ICARUS and set BITSIZE_in2 at least to $clog2(PRECISION), which is 5 in this case, then this module synthesizes fine with Yosys.
I'll keep this issue open until I have figured out how to do const evaluation of functions.
PS: When quoting code in markdown you should indent it with 4 spaces. Just for future reference, here is the code again, but quoted correctly (and with additional indenting for readability):
module lshift_expr_FU(in1, in2, out1);
parameter BITSIZE_in1=1, BITSIZE_in2=1, BITSIZE_out1=1, PRECISION=32;
// IN
input signed [BITSIZE_in1-1:0] in1;
input [BITSIZE_in2-1:0] in2;
// OUT
output signed [BITSIZE_out1-1:0] out1;
`ifndef __ICARUS__
function integer log2;
input integer value;
integer temp_value;
begin
temp_value = value-1;
for (log2=0; temp_value>0; log2=log2+1)
temp_value = temp_value>>1;
end
endfunction
`endif
`ifdef __ICARUS__
parameter arg2_bitsize = $clog2(PRECISION);
`else
parameter arg2_bitsize = log2(PRECISION);
`endif
assign out1 = in1 <<< in2[arg2_bitsize-1:0];
endmodule
from yosys.
First of all, thanks for the answer. You are right if you consider the module alone. What it is strange is the yosys behavior during the parsing of a more bigger example.
Here attached the large example that passes the xst/iverilog compilation:
// File automatically generated by: PandA framework version=0.9.2-dev
// Send any bug to: [email protected]
// ************************************************************************
// The following text holds for all the components tagged with PANDA_GPLv3.
//
// This hardware description is free; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This hardware description is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with the PandA framework; see the files COPYING
// If not, see <http://www.gnu.org/licenses/>.
// ************************************************************************
// This component is part of the BAMBU/PANDA IP LIBRARY
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): Fabrizio Ferrandi <fabrizio.ferrandi@xxxx>, Christian Pilato <christian.pilato@xxxx>
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module constant_value(out1);
parameter BITSIZE_out1=1, value=0;
// OUT
output [BITSIZE_out1-1:0] out1;
assign out1 = value;
endmodule
// This component is part of the BAMBU/PANDA IP LIBRARY
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): Fabrizio Ferrandi <fabrizio.ferrandi@xxxx>
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module register_SE(clock, reset, in1, wenable, out1);
parameter BITSIZE_in1=1, BITSIZE_out1=1;
// IN
input clock;
input reset;
input [BITSIZE_in1-1:0] in1;
input wenable;
// OUT
output [BITSIZE_out1-1:0] out1;
reg [BITSIZE_out1-1:0] reg_out1;
assign out1 = reg_out1;
always @(posedge clock)
if (wenable)
reg_out1 <= in1;
endmodule
// This component is part of the BAMBU/PANDA IP LIBRARY
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): Fabrizio Ferrandi <fabrizio.ferrandi@xxxx>
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module register_STD(clock, reset, in1, wenable, out1);
parameter BITSIZE_in1=1, BITSIZE_out1=1;
// IN
input clock;
input reset;
input [BITSIZE_in1-1:0] in1;
input wenable;
// OUT
output [BITSIZE_out1-1:0] out1;
reg [BITSIZE_out1-1:0] reg_out1;
assign out1 = reg_out1;
always @(posedge clock)
reg_out1 <= in1;
endmodule
// This component is part of the BAMBU/PANDA IP LIBRARY
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): Fabrizio Ferrandi <fabrizio.ferrandi@xxxx>
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module ASSIGN_SIGNED_FU(in1, out1);
parameter BITSIZE_in1=1, BITSIZE_out1=1;
// IN
input signed [BITSIZE_in1-1:0] in1;
// OUT
output signed [BITSIZE_out1-1:0] out1;
assign out1 = in1;
endmodule
// This component is part of the BAMBU/PANDA IP LIBRARY
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): Fabrizio Ferrandi <fabrizio.ferrandi@xxxx>
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module MEMORY_CTRL(clock, start_port, in1, in2, in3, sel_LOAD, sel_STORE, done_port, out1, Min_oe_ram, Mout_oe_ram, Min_we_ram, Mout_we_ram, Min_addr_ram, Mout_addr_ram, M_Rdata_ram, Min_Wdata_ram, Mout_Wdata_ram, Min_data_ram_size, Mout_data_ram_size, M_DataRdy);
parameter BITSIZE_in1=1, BITSIZE_in2=1, BITSIZE_in3=1, BITSIZE_out1=1, BITSIZE_Min_addr_ram=1, BITSIZE_Mout_addr_ram=1, BITSIZE_M_Rdata_ram=8, BITSIZE_Min_Wdata_ram=8, BITSIZE_Mout_Wdata_ram=8, BITSIZE_Min_data_ram_size=1, BITSIZE_Mout_data_ram_size=1;
// IN
input clock;
input start_port;
input [BITSIZE_in1-1:0] in1;
input [BITSIZE_in2-1:0] in2;
input [BITSIZE_in3-1:0] in3;
input sel_LOAD;
input sel_STORE;
input Min_oe_ram;
input Min_we_ram;
input [BITSIZE_Min_addr_ram-1:0] Min_addr_ram;
input [BITSIZE_M_Rdata_ram-1:0] M_Rdata_ram;
input [BITSIZE_Min_Wdata_ram-1:0] Min_Wdata_ram;
input [BITSIZE_Min_data_ram_size-1:0] Min_data_ram_size;
input M_DataRdy;
// OUT
output done_port;
output [BITSIZE_out1-1:0] out1;
output Mout_oe_ram;
output Mout_we_ram;
output [BITSIZE_Mout_addr_ram-1:0] Mout_addr_ram;
output [BITSIZE_Mout_Wdata_ram-1:0] Mout_Wdata_ram;
output [BITSIZE_Mout_data_ram_size-1:0] Mout_data_ram_size;
wire [BITSIZE_in2-1:0] tmp_addr;
assign tmp_addr = in2;
assign Mout_addr_ram = (sel_LOAD || sel_STORE) ? tmp_addr : Min_addr_ram;
assign Mout_oe_ram = sel_LOAD ? 1'b1 : Min_oe_ram;
assign Mout_we_ram = sel_STORE ? 1'b1 : Min_we_ram;
assign out1 = M_Rdata_ram[BITSIZE_out1-1:0];
assign Mout_Wdata_ram = sel_STORE ? in1 : Min_Wdata_ram;
assign Mout_data_ram_size = sel_STORE || sel_LOAD ? in3[BITSIZE_in3-1:0] : Min_data_ram_size;
assign done_port = M_DataRdy && (sel_STORE || sel_LOAD);
// Add assertion here
// psl default clock = (posedge clock);
// psl ERROR_Min_we_ram_Min_oe_ram: assert never {Min_we_ram && Min_oe_ram};
// psl ERROR_LOAD_Min_oe_ram: assert never {sel_LOAD && Min_oe_ram};
// psl ERROR_STORE_Min_we_ram: assert never {sel_STORE && Min_we_ram};
// psl ERROR_STORE_LOAD: assert never {sel_STORE && sel_LOAD};
// psl ERROR_wrong_address: assert never {(sel_STORE || sel_LOAD) && tmp_addr == 0};
endmodule
// This component is part of the BAMBU/PANDA IP LIBRARY
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): Fabrizio Ferrandi <fabrizio.ferrandi@xxxx>
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module plus_expr_FU(in1, in2, out1);
parameter BITSIZE_in1=1, BITSIZE_in2=1, BITSIZE_out1=1;
// IN
input signed [BITSIZE_in1-1:0] in1;
input signed [BITSIZE_in2-1:0] in2;
// OUT
output signed [BITSIZE_out1-1:0] out1;
assign out1 = in1 + in2;
endmodule
// This component is part of the BAMBU/PANDA IP LIBRARY
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): Fabrizio Ferrandi <fabrizio.ferrandi@xxxx>
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module lshift_expr_FU(in1, in2, out1);
parameter BITSIZE_in1=1, BITSIZE_in2=1, BITSIZE_out1=1, PRECISION=32;
// IN
input signed [BITSIZE_in1-1:0] in1;
input [BITSIZE_in2-1:0] in2;
// OUT
output signed [BITSIZE_out1-1:0] out1;
`ifndef __ICARUS__
function integer log2;
input integer value;
integer temp_value;
begin
temp_value = value-1;
for (log2=0; temp_value>0; log2=log2+1)
temp_value = temp_value>>1;
end
endfunction
`endif
`ifdef __ICARUS__
parameter arg2_bitsize = $clog2(PRECISION);
`else
parameter arg2_bitsize = log2(PRECISION);
`endif
assign out1 = in1 <<< in2[arg2_bitsize-1:0];
endmodule
// This component is part of the BAMBU/PANDA IP LIBRARY
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): Fabrizio Ferrandi <fabrizio.ferrandi@xxxx>
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module mult_expr_FU(clock, in1, in2, out1);
parameter BITSIZE_in1=1, BITSIZE_in2=1, BITSIZE_out1=1, PIPE_PARAMETER=0;
// IN
input clock;
input signed [BITSIZE_in1-1:0] in1;
input signed [BITSIZE_in2-1:0] in2;
// OUT
output signed [BITSIZE_out1-1:0] out1;
generate
if(PIPE_PARAMETER==1)
begin
reg signed [BITSIZE_in1-1:0] in1_in;
reg signed [BITSIZE_in2-1:0] in2_in;
assign out1 = in1_in * in2_in;
always @(posedge clock)
begin
in1_in <= in1;
in2_in <= in2;
end
end
else if(PIPE_PARAMETER>1)
begin
reg signed [BITSIZE_in1-1:0] in1_in;
reg signed [BITSIZE_in2-1:0] in2_in;
wire signed [BITSIZE_out1-1:0] mult_res;
reg signed [BITSIZE_out1-1:0] mul [PIPE_PARAMETER-2:0];
integer i;
assign mult_res = in1_in * in2_in;
always @(posedge clock)
begin
in1_in <= in1;
in2_in <= in2;
mul[PIPE_PARAMETER-2] <= mult_res;
for (i=0; i<PIPE_PARAMETER-2; i=i+1)
mul[i] <= mul[i+1];
end
assign out1 = mul[0];
end
else
begin
assign out1 = in1 * in2;
end
endgenerate
endmodule
// This component is part of the BAMBU/PANDA IP LIBRARY
// Copyright (C) 2013-2014 Politecnico di Milano
// Author(s): Fabrizio Ferrandi <fabrizio.ferrandi@xxxx>
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module bus_merger(in1, out1);
parameter BITSIZE_in1=1, PORTSIZE_in1=2, BITSIZE_out1=1;
// IN
input [(PORTSIZE_in1*BITSIZE_in1)+(-1):0] in1;
// OUT
output [BITSIZE_out1-1:0] out1;
function [BITSIZE_out1-1:0] merge;
input [BITSIZE_in1*PORTSIZE_in1-1:0] m;
reg [BITSIZE_out1-1:0] res;
integer i1;
begin
res={BITSIZE_in1{1'b0}};
for(i1 = 0; i1 < PORTSIZE_in1; i1 = i1 + 1)
begin
res = res | m[i1*BITSIZE_in1 +:BITSIZE_in1];
end
merge = res;
end
endfunction
assign out1 = merge(in1);
endmodule
// This component is part of the BAMBU/PANDA IP LIBRARY
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): Fabrizio Ferrandi <fabrizio.ferrandi@xxxx>
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module IUdata_converter_FU(in1, out1);
parameter BITSIZE_in1=1, BITSIZE_out1=1;
// IN
input signed [BITSIZE_in1-1:0] in1;
// OUT
output [BITSIZE_out1-1:0] out1;
generate
if (BITSIZE_out1 <= BITSIZE_in1)
begin
assign out1 = in1[BITSIZE_out1-1:0];
end
else
begin
assign out1 = {{(BITSIZE_out1-BITSIZE_in1){in1[BITSIZE_in1-1]}},in1};
end
endgenerate
endmodule
// This component is part of the BAMBU/PANDA IP LIBRARY
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): Fabrizio Ferrandi <fabrizio.ferrandi@xxxx>, Christian Pilato <christian.pilato@xxxx>
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module MUX_GATE(sel, in1, in2, out1);
parameter BITSIZE_in1=1, BITSIZE_in2=1, BITSIZE_out1=1;
// IN
input sel;
input [BITSIZE_in1-1:0] in1;
input [BITSIZE_in2-1:0] in2;
// OUT
output [BITSIZE_out1-1:0] out1;
assign out1 = sel ? in1 : in2;
endmodule
// Datapath RTL descrition for simple_mult_test
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): module automatically generated by bambu
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module datapath_simple_mult_test(clock, reset, in_port_a, in_port_b, in_port_res, M_Rdata_ram, M_DataRdy, Min_oe_ram, Min_we_ram, Min_addr_ram, Min_Wdata_ram, Min_data_ram_size, Mout_oe_ram, Mout_we_ram, Mout_addr_ram, Mout_Wdata_ram, Mout_data_ram_size, wrenable_reg_1, wrenable_reg_2, wrenable_reg_3, fuselector_MEMORY_CTRL_4_i0_LOAD, fuselector_MEMORY_CTRL_4_i0_STORE, selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0, selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0, selector_IN_UNBOUNDED_simple_mult_test_90450_90479, wrenable_reg_0, OUT_UNBOUNDED_simple_mult_test_90450_90479);
// IN
input clock;
input reset;
input signed [63:0] in_port_a;
input signed [63:0] in_port_b;
input [31:0] in_port_res;
input [63:0] M_Rdata_ram;
input M_DataRdy;
input Min_oe_ram;
input Min_we_ram;
input [31:0] Min_addr_ram;
input [63:0] Min_Wdata_ram;
input [6:0] Min_data_ram_size;
input wrenable_reg_1;
input wrenable_reg_2;
input wrenable_reg_3;
input fuselector_MEMORY_CTRL_4_i0_LOAD;
input fuselector_MEMORY_CTRL_4_i0_STORE;
input selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0;
input selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0;
input selector_IN_UNBOUNDED_simple_mult_test_90450_90479;
input wrenable_reg_0;
// OUT
output Mout_oe_ram;
output Mout_we_ram;
output [31:0] Mout_addr_ram;
output [63:0] Mout_Wdata_ram;
output [6:0] Mout_data_ram_size;
output OUT_UNBOUNDED_simple_mult_test_90450_90479;
// Component and signal declarations
wire signed [63:0] out_ASSIGN_SIGNED_FU_2_i0_fu_simple_mult_test_90450_90474;
wire [63:0] out_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0;
wire [63:0] out_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0;
wire [63:0] out_const_0;
wire [6:0] out_const_1;
wire [63:0] out_iu_conv_conn_obj_0_IUdata_converter_FU_iu_conv_0;
wire signed [63:0] out_lshift_expr_FU_64_0_64_6_i0_fu_simple_mult_test_90450_90512;
wire signed [63:0] out_mult_expr_FU_64_64_64_5_8_i0_fu_simple_mult_test_90450_90475;
wire signed [63:0] out_mult_expr_FU_64_64_64_5_8_i1_mult_expr_FU_64_64_64_5_8_i1;
wire signed [63:0] out_plus_expr_FU_64_0_64_7_i0_fu_simple_mult_test_90450_90477;
wire signed [63:0] out_plus_expr_FU_64_64_64_5_i0_fu_simple_mult_test_90450_90515;
wire [63:0] out_reg_0_reg_0;
wire [63:0] out_reg_1_reg_1;
wire [63:0] out_reg_2_reg_2;
wire [63:0] out_reg_3_reg_3;
wire s_done_fu_simple_mult_test_90450_90479;
wire [63:0] sig_in_bus_mergerMout_Wdata_ram10;
wire [31:0] sig_in_bus_mergerMout_addr_ram20;
wire [6:0] sig_in_bus_mergerMout_data_ram_size00;
wire sig_in_bus_mergerMout_oe_ram40;
wire sig_in_bus_mergerMout_we_ram30;
wire [63:0] sig_out_bus_mergerMout_Wdata_ram1;
wire [31:0] sig_out_bus_mergerMout_addr_ram2;
wire [6:0] sig_out_bus_mergerMout_data_ram_size0;
wire sig_out_bus_mergerMout_oe_ram4;
wire sig_out_bus_mergerMout_we_ram3;
IUdata_converter_FU #(.BITSIZE_in1(64), .BITSIZE_out1(64)) IUdata_converter_FU_iu_conv_0 (.out1(out_iu_conv_conn_obj_0_IUdata_converter_FU_iu_conv_0), .in1(out_reg_3_reg_3));
MUX_GATE #(.BITSIZE_in1(64), .BITSIZE_in2(64), .BITSIZE_out1(64)) MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0 (.out1(out_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0), .sel(selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0), .in1(out_reg_3_reg_3), .in2(out_reg_2_reg_2));
MUX_GATE #(.BITSIZE_in1(64), .BITSIZE_in2(64), .BITSIZE_out1(64)) MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0 (.out1(out_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0), .sel(selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0), .in1(out_reg_0_reg_0), .in2(out_reg_1_reg_1));
bus_merger #(.BITSIZE_in1(64), .PORTSIZE_in1(1), .BITSIZE_out1(64)) bus_mergerMout_Wdata_ram1 (.out1(sig_out_bus_mergerMout_Wdata_ram1), .in1({sig_in_bus_mergerMout_Wdata_ram10}));
bus_merger #(.BITSIZE_in1(32), .PORTSIZE_in1(1), .BITSIZE_out1(32)) bus_mergerMout_addr_ram2 (.out1(sig_out_bus_mergerMout_addr_ram2), .in1({sig_in_bus_mergerMout_addr_ram20}));
bus_merger #(.BITSIZE_in1(7), .PORTSIZE_in1(1), .BITSIZE_out1(7)) bus_mergerMout_data_ram_size0 (.out1(sig_out_bus_mergerMout_data_ram_size0), .in1({sig_in_bus_mergerMout_data_ram_size00}));
bus_merger #(.BITSIZE_in1(1), .PORTSIZE_in1(1), .BITSIZE_out1(1)) bus_mergerMout_oe_ram4 (.out1(sig_out_bus_mergerMout_oe_ram4), .in1({sig_in_bus_mergerMout_oe_ram40}));
bus_merger #(.BITSIZE_in1(1), .PORTSIZE_in1(1), .BITSIZE_out1(1)) bus_mergerMout_we_ram3 (.out1(sig_out_bus_mergerMout_we_ram3), .in1({sig_in_bus_mergerMout_we_ram30}));
constant_value #(.BITSIZE_out1(64), .value(64'b0000000000000000000000000000000000000000000000000000000000000001)) const_0 (.out1(out_const_0));
constant_value #(.BITSIZE_out1(7), .value(7'b1000000)) const_1 (.out1(out_const_1));
ASSIGN_SIGNED_FU #(.BITSIZE_in1(64), .BITSIZE_out1(64)) fu_simple_mult_test_90450_90474 (.out1(out_ASSIGN_SIGNED_FU_2_i0_fu_simple_mult_test_90450_90474), .in1(out_plus_expr_FU_64_64_64_5_i0_fu_simple_mult_test_90450_90515));
mult_expr_FU #(.BITSIZE_in1(64), .BITSIZE_in2(64), .BITSIZE_out1(64), .PIPE_PARAMETER(5)) fu_simple_mult_test_90450_90475 (.out1(out_mult_expr_FU_64_64_64_5_8_i0_fu_simple_mult_test_90450_90475), .clock(clock), .in1(in_port_a), .in2(in_port_a));
plus_expr_FU #(.BITSIZE_in1(64), .BITSIZE_in2(64), .BITSIZE_out1(64)) fu_simple_mult_test_90450_90477 (.out1(out_plus_expr_FU_64_0_64_7_i0_fu_simple_mult_test_90450_90477), .in1(in_port_b), .in2(out_const_0));
MEMORY_CTRL #(.BITSIZE_in1(64), .BITSIZE_in2(32), .BITSIZE_in3(7), .BITSIZE_out1(1), .BITSIZE_Min_addr_ram(32), .BITSIZE_Mout_addr_ram(32), .BITSIZE_M_Rdata_ram(64), .BITSIZE_Min_Wdata_ram(64), .BITSIZE_Mout_Wdata_ram(64), .BITSIZE_Min_data_ram_size(7), .BITSIZE_Mout_data_ram_size(7)) fu_simple_mult_test_90450_90479 (.done_port(s_done_fu_simple_mult_test_90450_90479), .Mout_oe_ram(sig_in_bus_mergerMout_oe_ram40), .Mout_we_ram(sig_in_bus_mergerMout_we_ram30), .Mout_addr_ram(sig_in_bus_mergerMout_addr_ram20), .Mout_Wdata_ram(sig_in_bus_mergerMout_Wdata_ram10), .Mout_data_ram_size(sig_in_bus_mergerMout_data_ram_size00), .clock(clock), .start_port(selector_IN_UNBOUNDED_simple_mult_test_90450_90479), .in1(out_iu_conv_conn_obj_0_IUdata_converter_FU_iu_conv_0), .in2(in_port_res), .in3(out_const_1), .sel_LOAD(fuselector_MEMORY_CTRL_4_i0_LOAD), .sel_STORE(fuselector_MEMORY_CTRL_4_i0_STORE), .Min_oe_ram(Min_oe_ram), .Min_we_ram(Min_we_ram), .Min_addr_ram(Min_addr_ram), .M_Rdata_ram(M_Rdata_ram), .Min_Wdata_ram(Min_Wdata_ram), .Min_data_ram_size(Min_data_ram_size), .M_DataRdy(M_DataRdy));
lshift_expr_FU #(.BITSIZE_in1(64), .BITSIZE_in2(64), .BITSIZE_out1(64), .PRECISION(64)) fu_simple_mult_test_90450_90512 (.out1(out_lshift_expr_FU_64_0_64_6_i0_fu_simple_mult_test_90450_90512), .in1(in_port_b), .in2(out_const_0));
plus_expr_FU #(.BITSIZE_in1(64), .BITSIZE_in2(64), .BITSIZE_out1(64)) fu_simple_mult_test_90450_90515 (.out1(out_plus_expr_FU_64_64_64_5_i0_fu_simple_mult_test_90450_90515), .in1(out_lshift_expr_FU_64_0_64_6_i0_fu_simple_mult_test_90450_90512), .in2(in_port_b));
mult_expr_FU #(.BITSIZE_in1(64), .BITSIZE_in2(64), .BITSIZE_out1(64), .PIPE_PARAMETER(5)) mult_expr_FU_64_64_64_5_8_i1 (.out1(out_mult_expr_FU_64_64_64_5_8_i1_mult_expr_FU_64_64_64_5_8_i1), .clock(clock), .in1(out_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0), .in2(out_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0));
register_SE #(.BITSIZE_in1(64), .BITSIZE_out1(64)) reg_0 (.out1(out_reg_0_reg_0), .clock(clock), .reset(reset), .in1(out_ASSIGN_SIGNED_FU_2_i0_fu_simple_mult_test_90450_90474), .wenable(wrenable_reg_0));
register_SE #(.BITSIZE_in1(64), .BITSIZE_out1(64)) reg_1 (.out1(out_reg_1_reg_1), .clock(clock), .reset(reset), .in1(out_plus_expr_FU_64_0_64_7_i0_fu_simple_mult_test_90450_90477), .wenable(wrenable_reg_1));
register_STD #(.BITSIZE_in1(64), .BITSIZE_out1(64)) reg_2 (.out1(out_reg_2_reg_2), .clock(clock), .reset(reset), .in1(out_mult_expr_FU_64_64_64_5_8_i0_fu_simple_mult_test_90450_90475), .wenable(wrenable_reg_2));
register_SE #(.BITSIZE_in1(64), .BITSIZE_out1(64)) reg_3 (.out1(out_reg_3_reg_3), .clock(clock), .reset(reset), .in1(out_mult_expr_FU_64_64_64_5_8_i1_mult_expr_FU_64_64_64_5_8_i1), .wenable(wrenable_reg_3));
// io-signal post fix
assign Mout_oe_ram = sig_out_bus_mergerMout_oe_ram4;
assign Mout_we_ram = sig_out_bus_mergerMout_we_ram3;
assign Mout_addr_ram = sig_out_bus_mergerMout_addr_ram2;
assign Mout_Wdata_ram = sig_out_bus_mergerMout_Wdata_ram1;
assign Mout_data_ram_size = sig_out_bus_mergerMout_data_ram_size0;
assign OUT_UNBOUNDED_simple_mult_test_90450_90479 = s_done_fu_simple_mult_test_90450_90479;
endmodule
// FSM based controller descrition for simple_mult_test
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): module automatically generated by bambu
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module controller_simple_mult_test(done_port, wrenable_reg_1, wrenable_reg_2, wrenable_reg_3, fuselector_MEMORY_CTRL_4_i0_LOAD, fuselector_MEMORY_CTRL_4_i0_STORE, selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0, selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0, selector_IN_UNBOUNDED_simple_mult_test_90450_90479, wrenable_reg_0, OUT_UNBOUNDED_simple_mult_test_90450_90479, clock, reset, start_port);
// IN
input OUT_UNBOUNDED_simple_mult_test_90450_90479;
input clock;
input reset;
input start_port;
// OUT
output done_port;
output wrenable_reg_1;
output wrenable_reg_2;
output wrenable_reg_3;
output fuselector_MEMORY_CTRL_4_i0_LOAD;
output fuselector_MEMORY_CTRL_4_i0_STORE;
output selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0;
output selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0;
output selector_IN_UNBOUNDED_simple_mult_test_90450_90479;
output wrenable_reg_0;
parameter [4:0] S_0 = 5'd0,
S_1 = 5'd1,
S_2 = 5'd2,
S_3 = 5'd3,
S_4 = 5'd4,
S_5 = 5'd5,
S_6 = 5'd6,
S_7 = 5'd7,
S_8 = 5'd8,
S_9 = 5'd9,
S_10 = 5'd10,
S_11 = 5'd11,
S_12 = 5'd12,
S_13 = 5'd13,
S_14 = 5'd14,
S_15 = 5'd15,
S_16 = 5'd16,
S_17 = 5'd17,
S_18 = 5'd18,
S_19 = 5'd19,
S_20 = 5'd20;
reg [4:0] _present_state, _next_state;
reg done_port;
reg wrenable_reg_1;
reg wrenable_reg_2;
reg wrenable_reg_3;
reg fuselector_MEMORY_CTRL_4_i0_LOAD;
reg fuselector_MEMORY_CTRL_4_i0_STORE;
reg selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0;
reg selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0;
reg selector_IN_UNBOUNDED_simple_mult_test_90450_90479;
reg wrenable_reg_0;
always @(posedge clock)
if (!reset) _present_state <= S_0;
else _present_state <= _next_state;
always @(_present_state or OUT_UNBOUNDED_simple_mult_test_90450_90479 or start_port)
begin
_next_state = S_0;
done_port = 1'b0;
wrenable_reg_1 = 1'b0;
wrenable_reg_2 = 1'b0;
wrenable_reg_3 = 1'b0;
fuselector_MEMORY_CTRL_4_i0_LOAD = 1'b0;
fuselector_MEMORY_CTRL_4_i0_STORE = 1'b0;
selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0 = 1'b0;
selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0 = 1'b0;
selector_IN_UNBOUNDED_simple_mult_test_90450_90479 = 1'b0;
wrenable_reg_0 = 1'b0;
case (_present_state)
S_0 :
if(~start_port)
begin
_next_state = S_0;
end
else
begin
wrenable_reg_1 = 1'b1;
wrenable_reg_0 = 1'b1;
_next_state = S_1;
end
S_1 :
begin
_next_state = S_2;
end
S_2 :
begin
_next_state = S_3;
end
S_3 :
begin
_next_state = S_4;
end
S_4 :
begin
_next_state = S_5;
end
S_5 :
begin
wrenable_reg_2 = 1'b1;
_next_state = S_6;
end
S_6 :
begin
selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0 = 1'b1;
_next_state = S_7;
end
S_7 :
begin
_next_state = S_8;
end
S_8 :
begin
_next_state = S_9;
end
S_9 :
begin
_next_state = S_10;
end
S_10 :
begin
_next_state = S_11;
end
S_11 :
begin
wrenable_reg_3 = 1'b1;
_next_state = S_12;
end
S_12 :
begin
selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0 = 1'b1;
_next_state = S_13;
end
S_13 :
begin
_next_state = S_14;
end
S_14 :
begin
_next_state = S_15;
end
S_15 :
begin
_next_state = S_16;
end
S_16 :
begin
_next_state = S_17;
end
S_17 :
begin
wrenable_reg_3 = 1'b1;
_next_state = S_18;
end
S_18 :
begin
fuselector_MEMORY_CTRL_4_i0_STORE = 1'b1;
selector_IN_UNBOUNDED_simple_mult_test_90450_90479 = 1'b1;
if (OUT_UNBOUNDED_simple_mult_test_90450_90479 == 1'b0)
begin
_next_state = S_19;
end
else
begin
_next_state = S_20;
end
end
S_19 :
begin
fuselector_MEMORY_CTRL_4_i0_STORE = 1'b1;
if (OUT_UNBOUNDED_simple_mult_test_90450_90479 == 1'b0)
begin
_next_state = S_19;
end
else
begin
_next_state = S_20;
end
end
S_20 :
begin
_next_state = S_0;
done_port = 1'b1;
end
default :
begin
done_port = 1'b0;
wrenable_reg_1 = 1'b0;
wrenable_reg_2 = 1'b0;
wrenable_reg_3 = 1'b0;
fuselector_MEMORY_CTRL_4_i0_LOAD = 1'b0;
fuselector_MEMORY_CTRL_4_i0_STORE = 1'b0;
selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0 = 1'b0;
selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0 = 1'b0;
selector_IN_UNBOUNDED_simple_mult_test_90450_90479 = 1'b0;
wrenable_reg_0 = 1'b0;
end
endcase
end
endmodule
// Top circuit for simple_mult_test
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): module automatically generated by bambu
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module simple_mult_test(clock, reset, start_port, done_port, a, b, res, M_Rdata_ram, M_DataRdy, Min_oe_ram, Min_we_ram, Min_addr_ram, Min_Wdata_ram, Min_data_ram_size, Mout_oe_ram, Mout_we_ram, Mout_addr_ram, Mout_Wdata_ram, Mout_data_ram_size);
// IN
input clock;
input reset;
input start_port;
input signed [63:0] a;
input signed [63:0] b;
input [31:0] res;
input [63:0] M_Rdata_ram;
input M_DataRdy;
input Min_oe_ram;
input Min_we_ram;
input [31:0] Min_addr_ram;
input [63:0] Min_Wdata_ram;
input [6:0] Min_data_ram_size;
// OUT
output done_port;
output Mout_oe_ram;
output Mout_we_ram;
output [31:0] Mout_addr_ram;
output [63:0] Mout_Wdata_ram;
output [6:0] Mout_data_ram_size;
// Component and signal declarations
wire OUT_UNBOUNDED_simple_mult_test_90450_90479;
wire fuselector_MEMORY_CTRL_4_i0_LOAD;
wire fuselector_MEMORY_CTRL_4_i0_STORE;
wire selector_IN_UNBOUNDED_simple_mult_test_90450_90479;
wire selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0;
wire selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0;
wire wrenable_reg_0;
wire wrenable_reg_1;
wire wrenable_reg_2;
wire wrenable_reg_3;
controller_simple_mult_test Controller_i (.done_port(done_port), .wrenable_reg_1(wrenable_reg_1), .wrenable_reg_2(wrenable_reg_2), .wrenable_reg_3(wrenable_reg_3), .fuselector_MEMORY_CTRL_4_i0_LOAD(fuselector_MEMORY_CTRL_4_i0_LOAD), .fuselector_MEMORY_CTRL_4_i0_STORE(fuselector_MEMORY_CTRL_4_i0_STORE), .selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0(selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0), .selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0(selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0), .selector_IN_UNBOUNDED_simple_mult_test_90450_90479(selector_IN_UNBOUNDED_simple_mult_test_90450_90479), .wrenable_reg_0(wrenable_reg_0), .OUT_UNBOUNDED_simple_mult_test_90450_90479(OUT_UNBOUNDED_simple_mult_test_90450_90479), .clock(clock), .reset(reset), .start_port(start_port));
datapath_simple_mult_test Datapath_i (.Mout_oe_ram(Mout_oe_ram), .Mout_we_ram(Mout_we_ram), .Mout_addr_ram(Mout_addr_ram), .Mout_Wdata_ram(Mout_Wdata_ram), .Mout_data_ram_size(Mout_data_ram_size), .OUT_UNBOUNDED_simple_mult_test_90450_90479(OUT_UNBOUNDED_simple_mult_test_90450_90479), .clock(clock), .reset(reset), .in_port_a(a), .in_port_b(b), .in_port_res(res), .M_Rdata_ram(M_Rdata_ram), .M_DataRdy(M_DataRdy), .Min_oe_ram(Min_oe_ram), .Min_we_ram(Min_we_ram), .Min_addr_ram(Min_addr_ram), .Min_Wdata_ram(Min_Wdata_ram), .Min_data_ram_size(Min_data_ram_size), .wrenable_reg_1(wrenable_reg_1), .wrenable_reg_2(wrenable_reg_2), .wrenable_reg_3(wrenable_reg_3), .fuselector_MEMORY_CTRL_4_i0_LOAD(fuselector_MEMORY_CTRL_4_i0_LOAD), .fuselector_MEMORY_CTRL_4_i0_STORE(fuselector_MEMORY_CTRL_4_i0_STORE), .selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0(selector_MUX_12_mult_expr_FU_64_64_64_5_8_i1_0_0_0), .selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0(selector_MUX_13_mult_expr_FU_64_64_64_5_8_i1_1_0_0), .selector_IN_UNBOUNDED_simple_mult_test_90450_90479(selector_IN_UNBOUNDED_simple_mult_test_90450_90479), .wrenable_reg_0(wrenable_reg_0));
endmodule
// Minimal interface for top component: simple_mult_test
// Copyright (C) 2004-2014 Politecnico di Milano
// Author(s): module automatically generated by bambu
// License: PANDA_GPLv3
`timescale 1ns / 1ps
module simple_mult_test_minimal_interface(clock, reset, start_port, a, b, res, M_Rdata_ram, M_DataRdy, done_port, Mout_oe_ram, Mout_we_ram, Mout_addr_ram, Mout_Wdata_ram, Mout_data_ram_size);
// IN
input clock;
input reset;
input start_port;
input signed [63:0] a;
input signed [63:0] b;
input [31:0] res;
input [63:0] M_Rdata_ram;
input M_DataRdy;
// OUT
output done_port;
output Mout_oe_ram;
output Mout_we_ram;
output [31:0] Mout_addr_ram;
output [63:0] Mout_Wdata_ram;
output [6:0] Mout_data_ram_size;
// Component and signal declarations
simple_mult_test simple_mult_test_i0 (.done_port(done_port), .Mout_oe_ram(Mout_oe_ram), .Mout_we_ram(Mout_we_ram), .Mout_addr_ram(Mout_addr_ram), .Mout_Wdata_ram(Mout_Wdata_ram), .Mout_data_ram_size(Mout_data_ram_size), .clock(clock), .reset(reset), .start_port(start_port), .a(a), .b(b), .res(res), .M_Rdata_ram(M_Rdata_ram), .M_DataRdy(M_DataRdy), .Min_oe_ram(1'b0), .Min_we_ram(1'b0), .Min_addr_ram(32'b00000000000000000000000000000000), .Min_Wdata_ram(64'b0000000000000000000000000000000000000000000000000000000000000000), .Min_data_ram_size(7'b0000000));
endmodule
from yosys.
First of all, thanks for the answer. You are right if you consider the module alone. What it is strange is the yosys behavior during the parsing of a more bigger example.
You are right. This is because yosys considers each module stand-alone before traversing the design hierarchy, while many other tools only consider the variations of the modules reachable from a given top module. I've now added this functionality to yosys. The following now works with the design you provided:
read_verilog -defer -D__ICARUS__ test.v
hierarchy -check -top simple_mult_test_minimal_interface
from yosys.
great it works!
Just few notes. Such kind of designs have been tested w.r.t. different simulators and RTL synthesis tools. So the impression is that the defer behavior should be the default one. Moreover, going in deep and checking the Verilog standard I've found this:
12.8 Elaboration
Elaboration
is the process that occurs between parsing and simulation. It binds modules to module
instances, builds the model hierarchy, computes parameter values, resolves hierarchical names,
establishes net connectivity, and prepares all of this for simulation. With the addition of generate
constructs, the order in which these tasks occur becomes significant.
...
So, my understanding is that parsing (read_verilog) should postpone parameter evaluation to the elaboration phase (hierarchy -check -top simple_mult_test_minimal_interface) as in the -defer case.
Anyway, thanks for adding the -defer option. In the next days I'll add a backend towards yosys to the PandA framework.
from yosys.
For "just synthesis" I fully agree. However, there are many things you can do with yosys where there is no dedicated top module (when you would use "hierarchy" without the -top option or even use "hierarchy" not at all, maybe even not operate on verilog input). Up until now it never was a problem that Yosys by default also creates an RTLIL representation of all modules with their default parameter values.
I have not found anything in the Verilog standard that would state explicitly that the default values of parameters would need to yield a valid module, but I honestly find it strange to choose default values that would yield an invalid module.. ;)
Just FYI:
From the way Yosys works it needs to evaluate the RTLIL of all modules to figure out what the "top-level modules" (12.1.1 of the standard) of the design are, creating a chicken-egg problem. The standard states:
Top-level modules are modules that are included in the source text, but do not appear in any module instantiation statement, as described in 12.1.2. This applies even if the module instantiation appears in a generate block that is not itself instantiated (see 12.4). A model shall contain at least one top-level module.
The "even if the module instantiation appears in a generate block that is not itself instantiated" part is here so that tools can figure out what the top modules are just by looking at the AST without evaluating it. Yosy does not do that. It evaluates the AST for the default parameters and looks at the RTLIL instead. The advantage of this behavior is that modules can come from different front-ends that do not share the same AST representation, thus better de-coupling the frontends.
The disadvantage is that the parameters need reasonable default values.
The thing here is that "read_verilog" does not only parse Verilog, it also creates the RTLIL representation. Such as read_ilang and future frontends such as read_blif do. In certain cases the use of "hierarchy" is optional (but it is recommended to always use it unless you really know what you are doing). As such it does more than "read_verilog" does in synopsys design compiler or xilinx vivado, where the command really only does the parsing.
I think the -defer option is an ok solution for implementing Verilog synthesis flows. I wont make it the default behavior, because the behavior deviates from the way Yosys frontends usually behave.
I'm looking forward to the PandA backend for Yosys.
from yosys.
I've now added very basic support for function calls in parameters. It is just enough to make your log2 function work. So now this also works without -D__ICARUS__:
read_verilog -defer test.v
hierarchy -check -top simple_mult_test_minimal_interface
At the moment I do not aim at complete support for constant functions in Yosys, so don't stress it with artificial test cases. But if you encounter a case of a constant function that you actually need do not hesitate to open a new issue with a test case and I will look into it.
PS: I've added a link to PandA on the "Links" page on the Yosys Website.
from yosys.
Related Issues (20)
- system verilog "import" command not recognized (ERROR: syntax error, unexpected TOK_ID) HOT 3
- check-git-abc in Makefile for the first compile time HOT 4
- `count_id(cell->name) == 0` failure HOT 1
- IDES4_MEM gowin module is missing HOT 2
- Feature Request: Add Support for Input Filelist Option HOT 8
- CologneChip synthesis fails silently (simulation discrepancies) HOT 2
- Yosys Synthesis Error: Hash Table Exceeded Maximum Size HOT 8
- support error for Aggregate Initialization and Replication HOT 1
- Unable to code FSM into binary format HOT 2
- Can't build from 0.42 tarball HOT 1
- ABC: execution of command failed return code 139. HOT 3
- Variable Part Selects HOT 5
- ABC: execution of command failed return code 137. HOT 5
- Yosys Optimization Error: Optimization Stuck in PEEPOPT Pass HOT 2
- Yosys Optimization Issue: Process Stuck at OPT_CLEAN Pass HOT 1
- Build issue with abc submodule HOT 2
- Optimization Sequence Induces Synthesis Errors Leading to Simulation Inconsistencies HOT 10
- Optimization Sequence Leads to Functionally Incorrect Synthesis Output in Yosys HOT 1
- Custom Yosys Passes Result in Faulty Synthesis and Simulation Errors HOT 5
- Any plans to add CDC linting? HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from yosys.