1
\$\begingroup\$

I have a 50Mhz master clock clk and from that I have a derived baudClock clock which runs at 9600bps.

I have a transmitter module that I want to follow a state machine flow every baudClock.

The transmitter module receives strings from an external module/testbench and puts them into a queue. I want the state machine to take an item from the queue and then reduce queueCount by one.

On the other hand, I would like to be able to add an item to the queue on a clk cycle.

I cannot implement something such as that below because I would then be assigning queueCount from 2 always processes (resulting in multiple driver errors).

always_ff @(posedge clk )
begin
  if( addToQueue )
  begin
    if( queueCount < MAX_ELEMENTS )
    begin
      textQueue[ queueCount ] = myString;
      queueCount ++;
    end
  end
end

always_ff @(posedge baudClock )
begin
  unique case( state )
    IDLE         : HandleIdle();
    GETNEXT      : HandleGetNextString();  // Decreases queueCount
    SENDSTART    : HandleSendStart();
    SENDDATA     : HandleSendData();
    SENDBYTEDONE : HandleSendByteDone();
  endcase
end  

How would I go about doing this? ie. What's the best way to share variables in reading/writing or producer/consumer scenarios?

\$\endgroup\$
5
  • \$\begingroup\$ baudTick is not really a variable ... it is a signal \$\endgroup\$
    – jsotola
    Commented Feb 2, 2020 at 1:23
  • \$\begingroup\$ Are you planning to implement this in an FPGA, a CPLD, an ASIC, or what? \$\endgroup\$
    – The Photon
    Commented Feb 2, 2020 at 1:25
  • \$\begingroup\$ @ThePhoton I'm planning on implementing this in an FPGA. \$\endgroup\$
    – SparkyNZ
    Commented Feb 2, 2020 at 1:47
  • \$\begingroup\$ @ThePhoton thanks for the answer. I was more or less doing what you'd suggested, just generating/counting/strobing the baud signal outside of the module. Sorry if my terminology is poor - I am a software developer and this is very new to me. \$\endgroup\$
    – SparkyNZ
    Commented Feb 2, 2020 at 2:34
  • \$\begingroup\$ @ThePhoton I guess the other thing I need to be mindful of is that an actual 9600 bps clock is going to keep the baudClock high for many master clock cycles.. So by "strobe" I guess you mean that I should only have the "strobe" high for one master clock cycle. \$\endgroup\$
    – SparkyNZ
    Commented Feb 2, 2020 at 2:42

1 Answer 1

2
\$\begingroup\$

In comments you said this is for implementation in an FPGA.

In that case, you should reconsider your architecture.

Instead of dividing down your 50 MHz master clock and having a second 9600 Hz clock, use the 50 MHz clock to drive your 9600 Hz logic, but use a strobe signal to enable that logic.

reg str9600;
reg [12:0] str_ct;

always @(posedge clk) begin
    // Generate 9600 baud strobe
    if (reset) begin
        str_ct <= 0;
        str9600 <= 0;
    end
    else if (str_ct == 5208) begin
        str_ct <= 0;
        str9600 <= 1;
    end
    else begin
        str_ct <= str_ct + 1;
        str9600 <= 0;
end

always @(posedge clk) begin
   // Do 9600 baud operations when enabled by strobe
   if (reset) 
        // reset stuff
   else if(str9600) 
        // do 9600 baud stuff
end

always @(posedge clk) begin
    // do 50 MHz stuff
    // queue management goes here
end

Now your queue becomes part of the 50 MHz logic, with the str9600 signal as an input, telling it whether something can be pulled out of the queue, but able to add to the queue on any 50 MHz clock edge.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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