Search code examples
verilogsynthesis

How to know whether a Verilog code can be synthesized?


I want to figure out whether Verilog syntax can be synthesized by doing practice. The RTL code is shown below:

module CRC10 (Clock, Data_In, CRC_En, CRC_Clr, CRC_Out);
input Clock;
input CRC_En;
input CRC_Clr;
output [9:0] CRC_Out;
//reg [9:0] CRC_Out;
input [31:0] Data_In;

reg CRC_En_reg;
reg CRC_Clr_reg;
reg [31:0] Data_In_reg;

always @ (posedge Clock)
begin
CRC_En_reg = CRC_En ;
CRC_Clr_reg = CRC_Clr ;
Data_In_reg = Data_In ;
end

reg crcfb;
reg [9:0] CRC_Reg;
integer i;

assign CRC_Out = CRC_Reg;

always @ (posedge Clock)
begin
    if (CRC_Clr_reg)
        CRC_Reg <= 0;
    else if (CRC_En_reg) 
    begin
        for (i=31;i>=0;i=i-1)
        begin
                   crcfb     <=CRC_Reg[9];
                   CRC_Reg[9]<=CRC_Reg[8]^crcfb;
                   CRC_Reg[8]<=CRC_Reg[7];
                   CRC_Reg[7]<=CRC_Reg[6];
                   CRC_Reg[6]<=CRC_Reg[5];
                   CRC_Reg[5]<=CRC_Reg[4]^crcfb;
                   CRC_Reg[4]<=CRC_Reg[3]^crcfb;
                   CRC_Reg[3]<=CRC_Reg[2];
                   CRC_Reg[2]<=CRC_Reg[1];
                   CRC_Reg[1]<=CRC_Reg[0]^crcfb;
                   CRC_Reg[0]<=Data_In_reg[i]^crcfb;
        end
    end
end
endmodule

I want to know if integer can be synthesized, so I made a simple design compile project. The file directory is shown below.

enter image description here

The following code is CRC10.sdc:

create_clock -name clk  -period 30.0   [get_ports  Clock]

set_dont_touch_network      [all_clocks]
set_fix_hold                [all_clocks]
set_clock_uncertainty  0.1  [all_clocks]
set_clock_latency      0.5  [all_clocks]
set_ideal_network           [get_ports clk]



#Don't touch the basic env setting as below
set_input_delay  5.0   -clock clk [remove_from_collection [all_inputs] [get_ports clk]]
set_output_delay 0.5    -clock clk [all_outputs]

set_load         1   [all_outputs]
set_drive        1   [all_inputs]

set_operating_conditions -max_library slow -max slow
set_wire_load_model -name tsmc13_wl10 -library slow
set_max_fanout 20 [all_inputs]

The following code is CRC10.tcl:

source .synopsys_dc.setup
read_verilog CRC10.v
link
source CRC10.sdc
set_fix_multiple_port_nets -all -buffer_constants [get_designs *] 
set verilogout_no_tri     true 

compile -inc

report_timing  -delay_type max >> setup_timing_max.txt;     #set up time
report_timing  -delay_type min >> setup_timing_min.txt;     #hold time 
report_area >> area.txt

write -hierarchy -format verilog -output  CRC10_syn.v
write_sdf -version 2.1 -context verilog  CRC10_syn.sdf
write -hierarchy -format ddc -output CRC10_syn.ddc

However, I don't see any error or warning about synthesis, so I am still not sure if the integer can be synthesized.

The following warning is reported by design compile:

enter image description here

The Data_In port is an input port; I don't know why it reports this.

If my thinking is wrong, please tell me the right way to do it.


Solution

  • I want to know if integer can be synthesized

    Yes, the way you use integer (as a for loop iterator) is supported by many synthesis tools.

    It is not obvious why you get the specific warning messages about Data_in because it looks like it drives a load properly. However, I see some questionable code.

    You should run simulations to make sure the design works the way you expect it to, before you run synthesis. Check the module output to make sure it gives you the correct output. The for loop is hard to understand. The simulator and synthesis tools "unroll" the loop, and you have multiple nonblocking assignments, which is usually not a good coding practice. For example, this line of code is executed 32 times on each posedge Clock (when enabled):

                   crcfb     <=CRC_Reg[9];
    

    The same is true for the 9 other assignments in the loop. The syntax is legal, but it makes the design intent hard to understand, and there are usually better coding styles to achieve what you want.

    Taking a closer look at the last line in the for loop, it unrolls to this:

    CRC_Reg[0]<=Data_In_reg[31]^crcfb;
    CRC_Reg[0]<=Data_In_reg[30]^crcfb;
    // ...
    CRC_Reg[0]<=Data_In_reg[1]^crcfb;
    CRC_Reg[0]<=Data_In_reg[0]^crcfb;
    

    After seeing a comment on the question by user mkrieger1, it is likely that the synthesis tool interprets the multiple assignments in that order (although I am unsure if this is an order guaranteed by the IEEE Std when unrolling a for loop). In that case, the last assignment takes precedence over the other 31 assignments to CRC_Reg[0]. It is as if the synthesis tool completely disregarded the other assignments. That would explain why the input bits 1 to 31 are not connected, whereas you do not get a warning about bit 0. Following good coding practices can avoid problems like this.