0
votes

this is a very basic question but if somebody can help me with these errors, I'd really appreciate it. I am an EE undergrad, new to Verilog, and I'd appreciate any help/explanation.

The errors I received were:

  • 10028 Can't resolve multiple constant drivers for "led" at compare_block.sv (66)
  • 10029 Constant driver at compare_block.sv(61)

What are the multiple constant drivers here? Originally, I had the led assignment (led <= led_val) within the second always block, and I thought moving it up to the first always block would change the errors, but it did not.

module compare_block (clk, reset_n, result, led);
    
    parameter data_width = 8; /
    parameter size = 1000;

    
    input clk, reset_n;
    input [data_width:0] result;
    logic [(data_width):0] data_from_rom; 
    logic [9:0] addr_to_rom;
    output reg led;
    
    reg [(data_width):0] comp_sig [size-1:0];
    reg [data_width:0] comp_sig_temp;
    reg [(data_width):0] filt_sig [size-1:0];
    reg [(data_width):0] ans_sig [size-1:0];
    
    integer i, iii;
    reg [9:0] ii ;
    integer sum_array;
    wire [(data_width+3):0] array_avg;
    reg [data_width:0] summed_arr [size-2 : 0];//container for all summation steps
    wire total_sum;
    reg ans_sig_done;
    reg [data_width : 0] summed_ans;
    reg [data_width:0] max_val, error_val;
    
    initial begin 
    i = 0;
    ii = 0;
    led=0;
    data_from_rom='b000000000;
    summed_ans='b000000000;
    max_val='b000000000;
    for (iii=0;iii<(size-1);iii=iii+1) begin
        filt_sig[iii]=0;
    ans_sig [iii]=0;    
    comp_sig[iii]=0;
    summed_arr[iii]=0;
    end
    end 
    
    //port map to ROM
    rom_compare ref_wave(
    .clk(clk),
    .addr(addr_to_rom), //text file?
    .data(data_from_rom)
    );
        
    //Moore FSM
    localparam [3:0]
    s0=0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5;
    
    reg [3:0] state_reg, state_next;
    initial state_next = 0;
    always @(posedge clk, negedge reset_n) begin 
        if (reset_n == 'b0) begin //reset is active low
            state_reg <= s0;
        end else begin
            state_reg <= state_next;
            led <= led_val;
        end
    end
            
    always @(state_reg) begin 
        state_next = state_reg; 
         led=0;
        case (state_reg)
            s0 : begin //initial state, reset state
                    if (!reset_n) begin
                        led <= 0;   
                        ii <= 0;
                        end else begin
                        state_next <= s1; 
                        end
                    end
            s1 : begin
                     if (ii>(size)) begin
                    ii <= 0;
                     end else begin
                     addr_to_rom <= ii;
                     state_next <= s2;
                     end
                     end
            s2 : begin
                     comp_sig_temp <= data_from_rom;
                     filt_sig [ii] <= result;
                     state_next <= s3;
                     end
            s3 : begin
                     comp_sig[ii] <= comp_sig_temp; 
                     state_next <= s4;
                     end
        s4 : begin
                     ans_sig[ii] <= filt_sig[ii] - comp_sig[ii]; 
                     state_next <= s5;
                     end
        s5 : begin

            if (ii>(size-2)) begin
                ans_sig_done = 1;
            end else begin
                ans_sig_done = 0;
            end
            
            ii <= ii+1;
            state_next <= s0;
            end
        endcase
    end 
    reg [(data_width+2):0] sum; 
    integer j;
        always @* begin
        sum = 0; 
        if (ans_sig_done == 1) begin  
          for (j=4; j<(size-1); j=j+2) begin
                sum = sum +ans_sig[j];  
            if (ans_sig[j] > max_val) begin
                max_val = ans_sig[j];
            end
          end
        end
        end

    assign array_avg = sum >> 'd3; //2^3 = 8

    always @(clk, result) begin //posedge clk, result
        filt_sig [i] <= result;
        i <= i + 1;
    end

    assign error_val = max_val >> 'd2; //approx 25% of max value of array   
    reg led_val;
    always @(*)
        begin 
        if (array_avg < error_val) begin
             led_val <= 'b1; 
        end else begin
             led_val <= 'b0;
        end
    end

endmodule
1

1 Answers

0
votes

I figured it out! The two instances were me trying to initialize one led = 0 in one always block and then assigning led <= led_val in another. You can't refer to an output in two different always blocks.