0
votes

I have 2 always blocks, and a finish_bcd wire signal in order to detect only when a conversion is done or not. After the conversion, I'd like to put it at 0 but it's in another always block...

wire finish_bcd;

bin2bcd BinTBcd (
 .binary(data),
 .thousands(w1),
 .hundreds(w2),
 .tens(w3),
 .ones(w4),
 .finish(finish_bcd)  //################ line 53
);

always @(posedge finish or posedge finish_bcd) begin
    if (finish_bcd == 1) begin
        case(enable)
            5'b00000: enable <= 5'b00001; //send the thousands
            5'b00001: enable <= 5'b00010; //send the hundreds
            5'b00010: enable <= 5'b00100; //send the tens
            5'b00100: enable <= 5'b01000; //send the ones
            5'b01000: enable <= 5'b10000; //send a ";"
            5'b10000: enable <= 5'b00000; // Everything is sent, I would like to do 'finish_bcd = 0;' here, at the end of the process in this always block.
            default: enable <= 5'b00000;
        endcase 
    end
end

The bin2bcd module is :

module bin2bcd (
    input [10:0] binary,
    output reg [3:0] thousands,
    output reg [3:0] hundreds,
    output reg [3:0] tens,
    output reg [3:0] ones,
    output reg finish);

integer i;

always @(binary) begin
    // set 100's, 10's, and 1's to zero
   thousands = 4'b0;
   hundreds = 4'b0;
   tens = 4'b0;
   ones = 4'b0;

   for (i=10; i>=0; i=i-1) begin
       // add 3 to columns >= 5
       if (thousands >= 5)
           thousands = thousands + 3;         
       if (hundreds >= 5)
           hundreds = hundreds + 3;
       if (tens >= 5)
           tens = tens + 3;
       if (ones >= 5)
           ones = ones + 3;
        // shift left one
       thousands = thousands << 1;
       thousands[0] = hundreds[3];
       hundreds = hundreds << 1;
       hundreds[0] = tens[3];
       tens = tens << 1;
       tens[0] = ones[3];
       ones = ones << 1;
       ones[0] = binary[i];
   end

     finish <= 1;  //############ line to detect when the conversion is done

end
endmodule

Another question: Why I cannot just change "reg finish_bcd;" in the top module ?

I got this error line 53 Reference to scalar reg 'finish_bcd' is not a legal net lvalue

I will synthesize this code for a Xilinx FPGA.

Edit:

I have a binary word, I want to send it by serial communication then I convert this binary (11bits) to BCD in order to send ASCII numbers. And I want to send everytime when "binary" changes. finish_bcd is used for detecting when the conversion is done in order to start sending data. The always @(posedge finish or posedge finish_bcd) begin block is used to change the state (in order to send the thousands then hundreds etc...

Then, binary changes, the conversion is done, finish_bcd = 1, it starts to send the data (thousands etc...) the end of each send is detected with finish Everything is working in simulation but since finish_bcd doesn't go to 0, when it sent all numbers, it stops. I need to reset finish_bcd at the end in order to detect a new binary change and start to send new values.

Thank you.

1
You should replace always @(binary) with always @* as they will synthesis to the same thing. This is a combinatorial block, finish will always be 1. NB: you never set it to any other value so it will not work in simulation.Morgan
always @(posedge finish or posedge finish_bcd) is used for a kind of a state machine. I only want to make the conversion when binary change, not everytime. But binary can change before the data is full sent.Alexis
Do you mean the conversion always block doesn't take time to get proceed ? Then I don't need to detect the end ?Alexis
Modifying a register in two processes will not work good in synthesis, as far as I know. It seems that the conversion takes a fixed number of cycles. You can use a counter enabled by finish_bcd and the value of enable to control it in the process in bin2bcd .Krouitch
always @* is combinatorial, this need to simulate in zero time. For a state machine you need to use a clock and imply flip-flops for state. always @(posedge clk) your posedge finish or posedge finish_bcd is not really implying a valid hardware structure. Using a data signal (finish) as a clock will lead to all sorts of timing issues at synthesis.Morgan

1 Answers

2
votes

always @* is combinatorial, this need to simulate in zero time. For a state machine you need to use a clock and imply flip-flops for state.

Combinatorial logic can not hold state, therefore is no good on its own for state machines. Combinatorial sections are often used in Moore FSM to decode state in to outputs (based on state).

bin2bcd module is combinatorial because there is no clock or flip-flops used to make it take more than 1 clock cycle, that means it takes 0 clock cycles. You have used a for loop, you may be referring to how many loops it takes to execute, the for loop specifies 10. But this is combinatorial so your implying loads of parallel hardware, just because it is a loop in verilog does not mean it reuses the comparators. If you want to minimise the hardware and take 10 clock cycles to compute the result you need to build a state machine to control and sequence it.

Part 2

posedge finish or posedge finish_bcd is not really implying a valid hardware structure.

In part you have two posedges in the sensitivity list, one is not being used a async reset or set. which means you have created a flip-flop with two clock inputs. This hardware structure simply does not exist.

In addition to this Using a data signal (finish) as a clock will lead to all sorts of timing issues at synthesis. Image this design as part of a bigger system and you have to balance all the clock trees, this becomes very difficult to almost impossible if you do not keep data and clocking separate.