UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Observer shrtique
Observer
527 Views
Registered: ‎08-22-2016

FSM loses one of the stages after synth

Jump to solution

Hello, guys.

I have Vivado 2015.4 and use SystemVerilog.

Previously I did several FSMs for AXI Stream masters and they work perfectly. But this time Vivado loses one of the stages and so the output signal for this stage after synth.

According to log file I lose state "TLAST" and signal m_axis_tlast:

.......
.......
INFO: [Synth 8-802] inferred FSM for state register 'state_reg' in module 'm_axis_remapper'
INFO: [Synth 8-5544] ROM "nextstate" won't be mapped to Block RAM because address size (1) smaller than threshold (5)
---------------------------------------------------------------------------------------------------
                   State |                     New Encoding |                Previous Encoding 
---------------------------------------------------------------------------------------------------
                    IDLE |                               00 |                              000
                   TUSER |                               01 |                              001
     KERNEL_TRANSMITTING |                               10 |                              010
     WAIT_FOR_NEW_KERNEL |                               11 |                              011
---------------------------------------------------------------------------------------------------
INFO: [Synth 8-3354] encoded FSM with state register 'state_reg' using encoding 'sequential' in module 'm_axis_remapper'
---------------------------------------------------------------------------------
.....
.....
---------------------------------------------------------------------------------
Start Area Optimization
---------------------------------------------------------------------------------
INFO: [Synth 8-3333] propagating constant 0 across sequential element (m_axis_tlast_reg)
WARNING: [Synth 8-3332] Sequential element (m_axis_tlast_reg) is unused and will be removed from module m_axis_remapper.
---------------------------------------------------------------------------------

 

The code of module is following:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

module m_axis_remapper #(

  parameter DATA_WIDTH       = 8,
  parameter IMAGE_KERNEL_12K = 64,
  parameter IMG_WIDTH        = 4096,
  parameter IMG_HEIGHT       = 3072

)(

  input  logic                                         i_clk,
  input  logic                                         i_aresetn,

  input  logic [0:IMAGE_KERNEL_12K-1] [DATA_WIDTH-1:0] i_image_kernel_remapped,
  input  logic                                         i_kernel_is_remapped,

  output logic [DATA_WIDTH-1:0]                        m_axis_tdata,
  output logic                                         m_axis_tvalid,
  output logic                                         m_axis_tuser,
  output logic                                         m_axis_tlast

);


//SIGNALS
typedef enum logic [2:0] {IDLE, TUSER, KERNEL_TRANSMITTING, WAIT_FOR_NEW_KERNEL, TLAST} statetype;
statetype state, nextstate;

logic [DATA_WIDTH-1:0] axis_tdata;
logic                  axis_tvalid;
logic                  axis_tuser;
logic                  axis_tlast;

logic                  en_counter, en_counter_reg;

logic [5:0]            kernel_addr_next_to_rd;
logic [10:0]           img_pixel_counter;
logic [10:0]           img_line_counter;
logic                  end_of_frame;
logic                  next_is_tlast;
//

//state_reg
always_ff @( posedge i_clk, negedge i_aresetn )
  begin
    if   ( ~i_aresetn ) state <= IDLE;
    else                state <= nextstate;	
  end
//
//

//data_reg
always_ff @( posedge i_clk, negedge i_aresetn )
  begin
    if ( ~i_aresetn ) begin
      m_axis_tdata   <= '{ default: 'b0};
      m_axis_tvalid  <= 1'b0;
      m_axis_tuser   <= 1'b0;
      m_axis_tlast   <= 1'b0;

      en_counter_reg <= 1'b0;

    end else begin
      m_axis_tdata   <= axis_tdata;
      m_axis_tvalid  <= axis_tvalid;	
      m_axis_tuser   <= axis_tuser;
      m_axis_tlast   <= axis_tlast;

      en_counter_reg <= en_counter;

    end   
  end
//
//


always_comb
  begin

    nextstate   = state;
    
    axis_tdata  = m_axis_tdata;
    axis_tvalid = 1'b0;
    axis_tuser  = 1'b0;
    axis_tlast  = 1'b0;

    en_counter  = en_counter_reg;

    case ( state )

     
      IDLE : begin

        en_counter = 1'b0;

        if ( i_kernel_is_remapped ) begin

          axis_tdata  = i_image_kernel_remapped [kernel_addr_next_to_rd];
          axis_tvalid = 1'b1;
          axis_tuser  = 1'b1;

          en_counter  = 1'b1;

          nextstate   = TUSER;

        end	

      end //IDLE
      

      TUSER : begin
      	axis_tdata  = i_image_kernel_remapped [kernel_addr_next_to_rd];
        axis_tvalid = 1'b1;

        nextstate   = KERNEL_TRANSMITTING;

      end //TUSER


      KERNEL_TRANSMITTING : begin
        
        //if we've finished kernel transmitting and next is not ready -> go waiting
      	if ( ( ~i_kernel_is_remapped ) && ( kernel_addr_next_to_rd == 0 ) ) begin
          axis_tdata  = 0;
          axis_tvalid = 1'b0;
          	
          en_counter = 1'b0;	
          nextstate  = WAIT_FOR_NEW_KERNEL;
        end	else begin

          axis_tdata  = i_image_kernel_remapped [kernel_addr_next_to_rd];
          axis_tvalid = 1'b1;
          
          nextstate = KERNEL_TRANSMITTING;
          
          //tlast should appear with the last pixel
          if ( img_pixel_counter == (IMG_WIDTH-2) ) begin	
            axis_tlast = 1'b1;
            nextstate  = TLAST;
          end 
        end	
      	

      end //KERNEL_TRANSMITTING


      WAIT_FOR_NEW_KERNEL : begin
        
        if ( i_kernel_is_remapped ) begin

          axis_tdata  = i_image_kernel_remapped [kernel_addr_next_to_rd];
          axis_tvalid = 1'b1;
          
          en_counter  = 1'b1;

          nextstate   = KERNEL_TRANSMITTING;

        end 

      end //WAIT_FOR_NEW_KERNEL	
      


      TLAST : begin
      	en_counter = 1'b0;

        nextstate  = WAIT_FOR_NEW_KERNEL;
        
        //end of frame
        if ( ( img_line_counter == (IMG_HEIGHT-1) ) && ( img_pixel_counter == (IMG_WIDTH-1) ) ) begin

          nextstate = IDLE;
        end	

      end //TLAST

      
      default : nextstate = IDLE;	

    endcase	
  
  end	
//
//


//COUNTER of transmitted pixels
always @( posedge i_clk, negedge i_aresetn )
  begin
    if ( ~i_aresetn ) begin
      img_pixel_counter <= 0;
      img_line_counter  <= 0;
    end else begin
      
      //use reg-ed signal to do counting of output pixels from 0 up to IMG_WIDTH-1
      if ( en_counter_reg ) begin
        img_pixel_counter <= img_pixel_counter + 1;
      end

      //the stuff below is better to do without minding of s_axis_tvalid
      if ( img_pixel_counter == IMG_WIDTH - 1 ) begin
      	img_pixel_counter  <= 0;
        img_line_counter   <= img_line_counter + 1;

        if ( img_line_counter == IMG_HEIGHT - 1 ) begin
          img_line_counter <= 0;	
        end 	
      end    
    end
  end 


always @( posedge i_clk, negedge i_aresetn )
  begin
    if ( ~i_aresetn ) begin
      kernel_addr_next_to_rd <= 0;
    end else begin
      
      //use signal (en_counter) directly form logic (e.g to know nextaddress during TUSER state)
      //state:                  <IDLE><TUSER><KERNEL_TRANSMITTING>
      //kernel_addr_next_to_rd: <0000><00001><2><3><4><5>........
      //img_pixel_counter:      <0000><00000><1><2><3><4>........ 
          
      if ( en_counter ) begin
        kernel_addr_next_to_rd <= kernel_addr_next_to_rd + 1;
      end
      
      //the stuff below is better to do without minding of s_axis_tvalid
      if ( kernel_addr_next_to_rd == IMAGE_KERNEL_12K - 1 ) begin
      	kernel_addr_next_to_rd  <= 0;
      end    
    end
  end 

//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
endmodule

But Simulation results are fine:


Simulation_result.PNG

 

 

 

 

 

 

 

Guys, do you have any idea of how to fix this problem?

0 Kudos
1 Solution

Accepted Solutions
Observer shrtique
Observer
479 Views
Registered: ‎08-22-2016

Re: FSM loses one of the stages after synth

Jump to solution

Guys... sorry for interrupting.

I finally found what was wrong....

In this module I have new resolution of Image 4096x3072.... and it doesn't feets to:

logic [10:0] img_pixel_counter

 

Solution is: logic [11:0] img_pixel_counter

0 Kudos
3 Replies
Scholar dpaul24
Scholar
506 Views
Registered: ‎08-07-2014

Re: FSM loses one of the stages after synth

Jump to solution

@shrtique,

Have not looked into the RTL details.

Assuming that you are looking into the correct synthesis log file, synthesis engine does that only when it deems that nothing meaningful is being done in that state, and that optimizing it out does not affect the logical behavior of that module.

--------------------------------------------------------------------------------------------------------
FPGA enthusiast!
All PMs will be ignored
--------------------------------------------------------------------------------------------------------
0 Kudos
Observer shrtique
Observer
427 Views
Registered: ‎08-22-2016

Re: FSM loses one of the stages after synth

Jump to solution

@dpaul24

Thanks for your answer.
I agree with you.
But how it's possible that synth engine throws away this "if statement"?

//tlast should appear with the last pixel
          if ( img_pixel_counter == (IMG_WIDTH-2) ) begin	
            axis_tlast = 1'b1;
            nextstate  = TLAST;
          end 

Please look at the module code, it's not too comprehensive.

I'm putting pixels to the output (m_axis_tdata) form the buffer (image_kernel_remapped). With these pixels I provide syn signals: tvalid, tuser(first pixel of frame) and tlast (last pixel of the line). These syc signals appear according to pixel counter.
I used such approach quite often and previously it worked... But now I don't have any ideas why this happens.

0 Kudos
Observer shrtique
Observer
480 Views
Registered: ‎08-22-2016

Re: FSM loses one of the stages after synth

Jump to solution

Guys... sorry for interrupting.

I finally found what was wrong....

In this module I have new resolution of Image 4096x3072.... and it doesn't feets to:

logic [10:0] img_pixel_counter

 

Solution is: logic [11:0] img_pixel_counter

0 Kudos