Verilog Two-way Communication Example

I'm finishing a project, and the requirement is two-way binding between function blocks inside our processor. I know what it is, but is there a “standard” or a good simple example?

The only thing I can think of is two devices when there is a data line between them and when X sends Y, a separate “sent” signal is provided. When Y receives the “received” signal, X is sent to another wire. As soon as X reads this received signal, it stops sending data on the data line and sets the sent wire to 0 or Z. Then Y also sets the received signal to 0 or Z.

All this is synchronous (on the same watch).

Is this the right way? I believe that it can become very dirty on a large scale, but I only work on a simple processor based battery.

+4
source share
3 answers

The most common simple handshake for a single synchronization domain will be a valid / ready confirmation.

If "X" is sent to "Y", then X has outputs dataand valid, and Y has an output ready.

X , . , X , , Y , .

, - . valid , , / , .

, Y , , Y , .

, , - , 4- "req/ack", .

1. req=1 ack=0
2. req=1 ack=1
3. req=0 ack=1
4. req=0 ack=0

, . .

+5

, , FSM / . go (req) , , .

reg go;
reg complete;

//abstracted FSM1
always @(posedge clk) begin
  case( fsm1_state )
    START_SUB : begin
      go              <= 1'b1;
      fsm1_next_state <= WAIT_SUB;
    end
    WAIT_SUB: begin
      if (complete == 1'b1) begin
        go              <= 1'b0;
        fsm1_next_state <= COMPLETED_SUB;
      end
      else begin
        go              <= 1'b1;         //Might not be required to hold high in Synch design
        fsm1_next_state <= WAIT_SUB;     // Holds state
      end
    end
    default: begin
      go              <= 1'b0;
      fsm1_next_state <= fsm1_state;
    end
  endcase
end

//fsm2
always @(posedge clk) begin
  case( fsm2_state )
    WAITING : begin
      complete        <= 1'b0;
      if (go ==1'b1) begin
        fsm2_next_state <= DOSOMETHING;
      end
      else begin
        fsm2_next_state <= WAITING;
      end 
    end
    DOSOMETHING : begin
      complete        <= 1'b1;
      fsm2_next_state <= WAITING;
      // if an async system wait until go is deasserted
      // rather than pulse complete for 1 cycle
    end
  endcase
end

reset .

0

I think you are looking for design arbiters. There are many different arbitration schemes. The simplest is a circular pattern. If someone wants to access a resource (for example, CPU or memory, etc.), then this module will approve the query string. He waits until the arbiter approves the grant line, after which he will be allowed to continue processing, knowing that he has dedicated access to the interface, which is controlled by the arbitrator.

-1
source

All Articles