ohmkara 1.0

a technical blog.

Archive for March 2009

verilog synchronous fifo (code)

with 3 comments

I would have preferred a log2() user defined function and fifo depth parameter as a decimal integer. But icarus verilog does not seem to let me — hence the inelegance for now…

///////////////////////////////////////////////
// Author: (28/03/2009 08:54)
// Module: sync_fifo.v
// Project:
// Description: Synchronous FIFO
//    data output (dout) is un-registered.
// Version: 1.0
/////////////////////////////////////////////////
module sync_fifo
   #(
      parameter DATA_WIDTH = 8,
      parameter LOG2_DEPTH = 3 // i.e. fifo depth=2**LOG2_DEPTH
   )
   (
      input [DATA_WIDTH-1:0]  din,
      input wr_en,
      input rd_en,
      output [DATA_WIDTH-1:0] dout,
      output full,
      output empty,
      input clk,
      input reset
   );

   parameter MAX_COUNT = 2**LOG2_DEPTH;
   reg   [LOG2_DEPTH-1 : 0]   rd_ptr;
   reg   [LOG2_DEPTH-1 : 0]   wr_ptr;
   reg   [DATA_WIDTH-1 : 0]   mem[MAX_COUNT-1 : 0];   //memory size: 2**LOG2_DEPTH
   reg   [LOG2_DEPTH : 0]     depth_cnt;

   always @(posedge clk) begin
      if(reset) begin
         wr_ptr <= 'h0;
         rd_ptr <= 'h0;
      end // end if
      else begin
         if(wr_en)begin
            wr_ptr <= wr_ptr+1;
         end
         if(rd_en)
            rd_ptr <= rd_ptr+1;
      end //end else
   end//end always

   assign empty= (depth_cnt=='h0);
   assign full = (depth_cnt==MAX_COUNT);

   //comment if you want a registered dout
   assign dout = rd_en ? mem[rd_ptr]:'h0;

   always @(posedge clk) begin
      if (wr_en)
         mem[wr_ptr] <= din;
   end //end always

   //uncomment if you want a registered dout
   //always @(posedge clk) begin
   //   if (reset)
   //      dout <= 'h0;
   //   else if (rd_en)
   //      dout <= mem[rd_ptr];
   //end

   always @(posedge clk) begin
      if (reset)
         depth_cnt <= 'h0;
      else begin
         case({rd_en,wr_en})
            2'b10    :  depth_cnt <= depth_cnt-1;
            2'b01    :  depth_cnt <= depth_cnt+1;
         endcase
      end //end else
   end //end always

endmodule

errata / addendum:
A better synchronous fifo might be — code below…

</pre>
///////////////////////////////////////////////
// Author: Deepak (28/03/2009 08:54)
// Module: fifo.v
// Project:
// Description: Synchronous FIFO
//    data output (dout) is un-registered.
// Version: 1.1 (not icarus verilog compatible)
//
///////////////////////////////////////////////

module sync_fifo
#(
 parameter DATA_WIDTH = 8,
 parameter DEPTH = 8</pre>
)
(
 input [DATA_WIDTH-1:0]  din,
 input wr_en,
 input rd_en,
 output [DATA_WIDTH-1:0] dout,
 output reg full,
 output reg empty,

 input clk,
 input reset
);

function integer log2;
 input integer n;
 begin
 log2 = 0;
 while(2**log2 < n) begin
 log2=log2+1;
 end
 end
endfunction

parameter ADDR_WIDTH = log2(DEPTH);
reg   [ADDR_WIDTH : 0]     rd_ptr; // note MSB is not really address
reg   [ADDR_WIDTH : 0]     wr_ptr; // note MSB is not really address
wire  [ADDR_WIDTH-1 : 0]  wr_loc;
wire  [ADDR_WIDTH-1 : 0]  rd_loc;
reg   [DATA_WIDTH-1 : 0]  mem[DEPTH-1 : 0];

assign wr_loc = wr_ptr[ADDR_WIDTH-1 : 0];
assign rd_loc = rd_ptr[ADDR_WIDTH-1 : 0];

always @(posedge clk) begin
 if(reset) begin
 wr_ptr <= 'h0;
 rd_ptr <= 'h0;
end // end if
else begin
 if(wr_en & (~full))begin
 wr_ptr <= wr_ptr+1;
 end
 if(rd_en & (~empty))
 rd_ptr <= rd_ptr+1;
 end //end else
end//end always

//empty if all the bits of rd_ptr and wr_ptr are the same.
//full if all bits except the MSB are equal and MSB differes
always @(rd_ptr or wr_ptr)begin
 //default catch-alls
 empty <= 1'b0;
 full  <= 1'b0;
 if(rd_ptr[ADDR_WIDTH-1:0]==wr_ptr[ADDR_WIDTH-1:0])begin
 if(rd_ptr[ADDR_WIDTH]==wr_ptr[ADDR_WIDTH])
 empty <= 1'b1;
 else
 full  <= 1'b1;
 end//end if
end//end always

always @(posedge clk) begin
 if (wr_en)
 mem[wr_loc] <= din;
end //end always

//comment if you want a registered dout
assign dout = rd_en ? mem[rd_loc]:'h0;
//uncomment if you want a registered dout
//always @(posedge clk) begin
//   if (reset)
//      dout <= 'h0;
//   else if (rd_en)
//      dout <= mem[rd_ptr];
//end
endmodule
Advertisements

Written by deepak

March 29, 2009 at 9:28 am

Posted in hdl

Tagged with

gnome — send to USB drive / removable disk

leave a comment »

You can add a right-click able send to USB drive option in gnome with the “Send To” script available here: link; the target/ destination could be any writeable file-system mounted at /media.  . Such a feature is available in xfce, I was missing the same in gnome, I feel that it is a mighty nice feature to have.

You have to copy the link to ~/gnome2/nautilus-scripts and make it executable (chmod). Right clicking will thereafter present an option called ‘Scripts’ which is the required action.

Ack: I got this info @ this site: link.

Written by deepak

March 21, 2009 at 9:07 pm

Posted in links, linux

Tagged with

comment boxes — verilog in vim

leave a comment »

I have recently started learning verilog (used to use vhdl) and using vim as the editor of choice. I wanted some easy way to insert verilog comment boxes in file — something like…

///////////////////////////////////////////////
// Author: Deepak (18/03/2009 21:22)
// Module: xxxxx.v
// Project: yyyyy
// Description: some random module.
//
///////////////////////////////////////////////

I added an abbreviation, as follows, in the .vimrc file…

:iab #b ///////////////////////////////////////////////<CR> Author: Deepak (<C-R>=strftime(“%d/%m/%Y %H:%M”)<CR>) <CR>Module: .v <CR>Project: <CR>Description: <CR><CR><BS>/////////////////////////////////////////////

Typing #b does the trick. What this gives me is (in case you are not Neo – the one) is the following ‘template’.

///////////////////////////////////////////////
// Author: Deepak (18/03/2009 21:22)
// Module: .v
// Project:
// Description:
//
///////////////////////////////////////////////

There are other ways to do this, like adding a macro as shown here — link, or with boxes. But I felt that typing on in insert mode is less intrusive.

Written by deepak

March 19, 2009 at 10:41 pm

Posted in Uncategorized

learn to touch type

leave a comment »

I think that touch typing is a useful skill to have, more so for people like me — slated to spend a considerable portion of their life @ coding. I have just started to learn — the tool I am using to learn touch typing is gtypist (GNU Typist) available here — link. Both linux and windows versions are available. It has just a plain text look, nothing fancy, but I liked the tool.

Written by deepak

March 18, 2009 at 11:14 am

Posted in links, tools

Tagged with