2010년 1월 23일 토요일

Sync FIFO verilog code with external and single port SRAM

 module sync_fifo(

   Reset, Clk, Rd, Wr, Full, Empty, Din, Dout,
   addr, Data, nCS, nOE, nWE
);

parameter ADDR_SIZE = 18;
parameter DATA_SIZE = 16;

input Reset;
input Clk;
input Rd;
input Wr;
output Full;
output Empty;
input [DATA_SIZE-1:0] Din;
output [DATA_SIZE-1:0] Dout;
output [ADDR_SIZE-1:0] Addr;
inout [DATA_SIZE-1:0] Data;
output nCS;
output nOE;
output nWE;

// write address counter
reg [ADDR_SIZE:0] write_addr;
always @(posedge Clk) begin
   if (Reset) begin
      write_addr <= 0;
   end else begin
      if (Wr) write_addr <= write_addr+1;
   end
end

// read address counter
reg [ADDR_SIZE:0] read_addr;
always @(posedge Clk) begin
   if (Reset) begin
      read_addr <= 0;
   end else begin
      if (Rd) read_addr <= read_addr+1;
   end
end

reg Full;
reg Empty;
always @(write_addr or read_addr) begin
   if (~|(write_addr[ADDR_SIZE-1:0]^read_addr[ADDR_SIZE-1:0])) begin
      if (~|(write_addr[ADDR_SIZE]^read_addr[ADDR_SIZE])) begin
         Empty <= 1'b1;
         Full <= 1'b0;
      end else begin
         Empty <= 1'b0;
         Full <= 1'b1;
      end
   end else begin
      Empty <= 1'b0;
      Full <= 1'b0;
   end
end

assign nCS = ~(Wr | Rd);
assign nOE = ~(Rd);
assign nWE = ~(Wr);
assign Addr = Wr ? write_addr[ADDR_SIZE-1] : read_addr[ADDR_SIZE-1];
assign Data = Wr ? Din : 16'bz;
assign Dout = Rd ? Data : 16'bz;

endmodule

댓글 2개:

  1. 이거 잘못 짜니 코드입니다. 풀, 엠티 상태를 제대로 검출하지 못하네요.

    답글삭제
  2. 현재 사용중인 코드 입니다. 메모리 어드레스의 최상위 비트는 실제로 사용하는 것이 아니라 Full, Empty상태를 구분하기 위해서 사용하는 것입니다.

    답글삭제