0
\$\begingroup\$

Edit: it is something with the simulate_camera_output module that Modelsim doesn't like. Tried with a simple test module and it works fine.

Looking for a way to get a Modelsim compilation log.

`timescale 1ps / 1ps
module Cam_tb  ; 

  wire    CamSIOD   ; 
  wire    CamVSYNC   ; 
  wire    HREF   ; 
  wire  [7:0]  CamD   ; 
  wire    CamHREF   ; 
  wire    VSYNC   ; 
  wire  [23:0]  RGB   ; 
  reg    CamSIOC   ; 
  reg    CamPCLK   ; 
  Cam  
   DUT  ( 
       .CamSIOD (CamSIOD ) ,
      .CamVSYNC (CamVSYNC ) ,
      .HREF (HREF ) ,
      .CamD (CamD ) ,
      .CamHREF (CamHREF ) ,
      .VSYNC (VSYNC ) ,
      .RGB (RGB ) ,
      .CamSIOC (CamSIOC ) ,
      .CamPCLK (CamPCLK ) );


  parameter clock_period = (1000 / 24);
  parameter clock_half_period = clock_period / 2;
  parameter sim_time = clock_period * 300;  


  initial
  begin
      CamPCLK  = 1'b0  ;
  end

  always #(clock_half_period) CamPCLK = ~CamPCLK;

  simulate_camera_output sim_cam_out(.CamHREF(CamHREF), .CamVSYNC(CamVSYNC), .CamPCLK(CamPCLK), .CamD(CamD));

  initial
  begin
    #(sim_time) $stop;
  end   


endmodule


module simulate_camera_output(CamHREF, CamVSYNC, CamPCLK, CamD);
      output CamHREF, CamVSYNC, CamPCLK;
        output [7:0] CamD;

        parameter data_clocks = 16;
        parameter h_f_porch = 3;
        parameter h_h_sync = 2;
        parameter h_b_porch = 5;
        parameter h_line_clocks = data_clocks + h_f_porch + h_h_sync + h_b_porch;

      integer current_clock = 0;
        integer Y1 = 1;     
        integer Cb = 2;
        integer Cr = 3;
        integer Y2 = 4;

        assign CamHREF = current_clock < data_clocks;
        assign CamVSYNC = 0;
        assign CamD = (current_clock < data_clocks) ? (current_clock % 4 == 0 ? Cb : (current_clock % 4 == 1 ? Y1 : (current_clock % 4 == 2 ? Cr : Y2))) : 8'bZZZZZZZZ;


      always @(posedge CamPCLK)
      begin

           current_clock = current_clock < h_line_clocks ? current_clock + 1 : 0;

            if(current_clock%4 == 0 && CamHREF)
            begin
           Y1 = Y1 + 10;
              Y2 = Y2 + 10;
              Cb = Cb + 10;
              Cr = Cr + 10;             
            end
      end  

  endmodule

The main testbench module is Cam_tb and the second simulate_camera_output module is in the same file.

I tried "Analyze current file" and it completed successfully.

When I run "RTL Simulation" from Quartus Prime with the simulate_camera_output module instantiation commented out Modelsim starts up and displays the clock waveform as expected.

When I uncomment the module instantiation and run "RTL Simulation" Modelsim starts up but I end up with all panes blank.

Where should I look to get error messages for what goes wrong in this case?

Or is it just taking long to run? (I don't see any messages about a simulation in progress)

This is what I get in the Messages window in Quartus Prime:

Info (22036): Successfully launched NativeLink simulation (quartus_sh -t "c:/intelfpga_lite/18.0/quartus/common/tcl/internal/nativelink/qnativesim.tcl" --rtl_sim "CamRamVga" "CamRamVga")
Info (22036): For messages from NativeLink execution see the NativeLink log file C:/projects/Camera-RAM-VGA/CamRamVga_nativelink_simulation.rpt

The CamRamVga_nativelink_simulation.rpt file looks fine.

Modelsim blank window after clicking "RTL Simulation"

The code of the DUT Cam module:

module Cam(CamPCLK, CamD, CamHREF, CamVSYNC, CamSIOD, CamSIOC,
           RGB, HREF, VSYNC);  
    input CamPCLK;
    input [7:0] CamD;   
    input CamHREF, CamVSYNC, CamSIOC;   
    inout CamSIOD;
    output [23:0] RGB;
    output HREF, VSYNC;

    //todo: add appropriate delays for HREF and VSYNC

    assign HREF = CamHREF;
    assign VSYNC = CamVSYNC;


   reg [1:0] InCmpnt = 0;
    reg [24:0] InQPar[1:0];
    reg [24:0] InQSer[1:0];
    reg [23:0] YCbCrPx;

    wire InQReady = (InQSer[0][24] == 1);
    wire InQCLK = (InCmpnt == 2'd0 || InCmpnt == 2'd2);


    always @(posedge CamPCLK && (CamHREF == 0 && !InQReady))
    begin       
         InCmpnt <= 0;
         InQPar[0][24:0] <= 0;
         InQPar[1][24:0] <= 0;
    end


    always @(posedge CamPCLK && (CamHREF == 1 || InQReady))
    begin
       InCmpnt <= InCmpnt + 1;

        case(InCmpnt)
           2'd0: //Cb
              begin
               InQPar[0][24] <= CamHREF;
               InQPar[0][15:8] <= CamD[7:0];
                InQPar[1][15:8] <= CamD[7:0];

                InQSer[0][24:0] <= InQPar[0][24:0];
                InQSer[1][24:0] <= InQPar[1][24:0];             


                //todo: XXXXYYYY find a way to re-use code blocks without typing twice (like macros)
              end
           2'd1: //Y0
              begin
               InQPar[0][23:16] <= CamD[7:0];

            YCbCrPx <= InQSer[0][23:0];
                InQSer[0][24:0] <= InQSer[1][24:0];             
                InQSer[1][24:0] <= 0;
              end
           2'd2: //Cr
              begin
               InQPar[1][24] <= CamHREF;
               InQPar[0][7:0] <= CamD[7:0];
                InQPar[1][7:0] <= CamD[7:0];
              end
           2'd3:    //Y1
              begin
               InQPar[1][23:16] <= CamD[7:0];

                YCbCrPx <= InQSer[0][23:0];
                InQSer[0][24:0] <= InQSer[1][24:0];             
                InQSer[1][24:0] <= 0;               
              end
            default: //Y0
              begin
               InQPar[0][24] <= CamHREF;
               InQPar[0][15:8] <= CamD[7:0];
                InQPar[1][15:8] <= CamD[7:0];

                InQSer[0][24:0] <= InQPar[0][24:0];
                InQSer[1][24:0] <= InQPar[1][24:0];
              end               
       endcase
    end

endmodule
\$\endgroup\$
1
\$\begingroup\$

The problem is not in your synthesizable module, it's in your testbench. So it's no wonder Quartus didn't catch it --- Quartus will only be trying to compile the actual function module, Cam.

You decleare CamPCLK as reg in the top level module.

Then you set it in the initial and always blocks.

But you also connect it to the CamPCLK port of sim_cam_out.

But the CamPCLK port of your simulate_camera_output module is an output, not an input.

First, a signal connected to the output of a module instance must be a wire, not a reg. Second, you can't assign the value of CamPCLK from two different places.

\$\endgroup\$
  • \$\begingroup\$ I think I did compile the tesbench module in Quartus using "Processing > Analyze Current File" and it compiled fine. \$\endgroup\$ – axk Sep 15 '18 at 19:48
  • \$\begingroup\$ OK, I don't know enough about Quartus to know why that would happen, but normally we only synthesize the design we actually want to put into the FPGA. The testbench is just included in the project to be used as an input to a simulation. \$\endgroup\$ – The Photon Sep 15 '18 at 19:50
0
\$\begingroup\$

The main takeaway for me is that Quartus Prime and Modelsim have different Verilog compilers and what compiles in Quartus doesn't not necessarily compile in Modelsim.

The window in Modelsim I was looking for is under View > Transcript

The error in my particular case is

# vsim work.Cam_tb 
# Start time: 20:46:26 on Sep 15,2018
# Loading work.Cam_tb
# Loading work.Cam
# Loading work.simulate_camera_output
# ** Error (suppressible): (vsim-3053) C:/projects/Camera-RAM-VGA/simulation/modelsim/Cam_tb.v(39): Illegal output or inout port connection for port 'CamPCLK'.
#    Time: 0 ps  Iteration: 0  Instance: /Cam_tb/sim_cam_out File: C:/projects/Camera-RAM-VGA/simulation/modelsim/Cam_tb.v
# Error loading design
# Error: Error loading design
#        Pausing macro execution
# MACRO ./CamRamVga_run_msim_rtl_verilog.do PAUSED at line 13
\$\endgroup\$
  • \$\begingroup\$ Did you compile your testbench in Quartus? Because the bug is in your testbench, not the synthesizable code I'd expect you to compile in Quartus. \$\endgroup\$ – The Photon Sep 15 '18 at 19:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.