Notes
This illustrates larger if...else blocks. The unit accepts data into the fifo asynchronously and clocks it out synchronously. The double latching of in_cmd_val is for demetastability. This example has been updated so it performs non-blocking assignments properly and doesn't cause feedback loops in the compiler.
/* * fifo.v * demonstrates use of behavioral synthesis extension constructs * 17aug99ajb */ module fifo(in_cmd_val, in_cmd_ack, in_cmd, pop_cmd, out_cmd, q_empty, q_full, q_valid, pci_rst, ck); input in_cmd_val; output in_cmd_ack; input [15:0] in_cmd; input pop_cmd; output [15:0] out_cmd; output q_empty; output q_full; output q_valid; input pci_rst; input ck; // ------------------------ latch declarations ------------------------------ reg [7:0] fifo_start_l2, fifo_end_l2, fifo_valid_l2; reg [15:0] fifo0_l2, fifo1_l2, fifo2_l2, fifo3_l2, fifo4_l2, fifo5_l2, fifo6_l2, fifo7_l2; reg in_cmd_val_a_l2, in_cmd_val_b_l2, in_cmd_ack_a_l2; // ------------------------ signal declarations ----------------------------- wire q_ok; wire [15:0] zero16 = 16'b0000_0000_0000_0000; // ----------------------------- mainline ----------------------------------- // // fifo queue up op (only if room) // assign q_ok = ((fifo_start_l2 & fifo_valid_l2) == 8'b0); assign q_valid = ((fifo_end_l2 & fifo_valid_l2) != 8'b0); assign q_empty = fifo_valid_l2 == 8'b0; assign q_full = fifo_valid_l2 == 8'hff; assign in_cmd_ack = in_cmd_ack_a_l2; // output port version/demeta of this sig always @(posedge ck) begin in_cmd_val_a_l2 <= in_cmd_val; // demetastability in_cmd_val_b_l2 <= in_cmd_val_a_l2; if (pci_rst==1'b1) // reset default begin fifo_start_l2 <= 8'h01; fifo_valid_l2 <= 8'h00; in_cmd_ack_a_l2 <= 1'b0; fifo0_l2 <= zero16; fifo1_l2 <= zero16; fifo2_l2 <= zero16; fifo3_l2 <= zero16; fifo4_l2 <= zero16; fifo5_l2 <= zero16; fifo6_l2 <= zero16; fifo7_l2 <= zero16; end else begin if (in_cmd_val_b_l2 & q_ok & ~in_cmd_ack_a_l2) // accept fifo data prior to handshake back begin in_cmd_ack_a_l2 <= 1'b1; fifo_start_l2 <= { fifo_start_l2[6:0], fifo_start_l2[7] }; // bump forward once if(fifo_start_l2[0]) fifo0_l2<=in_cmd; if(fifo_start_l2[1]) fifo1_l2<=in_cmd; if(fifo_start_l2[2]) fifo2_l2<=in_cmd; if(fifo_start_l2[3]) fifo3_l2<=in_cmd; if(fifo_start_l2[4]) fifo4_l2<=in_cmd; if(fifo_start_l2[5]) fifo5_l2<=in_cmd; if(fifo_start_l2[6]) fifo6_l2<=in_cmd; if(fifo_start_l2[7]) fifo7_l2<=in_cmd; end fifo_valid_l2 <= (fifo_valid_l2 | ( // update valid bits fifo_start_l2 & {8{in_cmd_val_b_l2 & q_ok & ~in_cmd_ack_a_l2}} )) & (~fifo_end_l2 | {8{~pop_cmd}}); if (in_cmd_ack_a_l2 & ~in_cmd_val_b_l2) in_cmd_ack_a_l2 <= 1'b0; // finish up handshake end end // // dequeue op // assign out_cmd = // output mux (fifo0_l2 & {16{fifo_end_l2[0]}})| (fifo1_l2 & {16{fifo_end_l2[1]}})| (fifo2_l2 & {16{fifo_end_l2[2]}})| (fifo3_l2 & {16{fifo_end_l2[3]}})| (fifo4_l2 & {16{fifo_end_l2[4]}})| (fifo5_l2 & {16{fifo_end_l2[5]}})| (fifo6_l2 & {16{fifo_end_l2[6]}})| (fifo7_l2 & {16{fifo_end_l2[7]}}); always @(posedge ck) if (pci_rst) // reset default fifo_end_l2 <= 8'h01; else if (pop_cmd) // increment on pop cmd fifo_end_l2 <= {fifo_end_l2[6:0],fifo_end_l2[7]}; endmodule