Wednesday, September 11, 2013

Reverse a singly linked list


static void _inPlaceRev( Node *cursor, Node *prev) {
  if(!cursor) { 
    return;
  }
  _inPlaceRev(head, tail, cursor->next, cursor);
  cursor->next = prev;
}

static void inPlaceRev(LinkedList * _my) {
  _inPlaceRev(_my->head, NULL);
  //swap the head and tail
  _my->head ^= _my->tail;
  _my->tail ^= _my->head;
  _my->head ^= _my->tail;

}

Monday, May 13, 2013

Object Oriented C

Since C is the mother of all the object oriented languages such as Objective c, c++, java, c#, and everything else, then C should have had SOME ability to be object oriented.

Object orientation is really, a pattern that helps reduce low level problems, such as memory management and encapsulation.  So, before Object oriented patterns became native, people in C would make the pattern.  I have made something that resembles that pattern.

The pattern includes:
1) data encapsulation
2) public member functions.

Object Oriented Linked List

Thursday, March 14, 2013

Send STDERR to terminal output. STDOUT to file

How to send STDERR to the terminal output and the STDOUT to a file.

Normally the STDOUT and STDERR are both sent to the terminal output.

To split them up we can use ">" and "2>" for STDOUT and STDERR respectively.

generic example
( cool_prog > cool_file ) 2>&1

**note, the parentheses are required or else it will not work**

The Explanation:

cool_prog will attempt to send thing into STDOUT.  The ">" will send it into cool_file.
cool_prog will attempt to send thing into STDERR.  The "2>&1" will send it to terminal output.

">&" should achieve the same effect as "2>&1"

To find more look at these links

http://www.macobserver.com/tips/macosxcl101/2002/20020607.shtml

http://www.tldp.org/LDP/abs/html/io-redirection.html

Friday, January 18, 2013

How to use cellular ram from micron M45W8MW16

Purpose/Goal/Desire:
To use the micron cellular ram as if it was a block ram.
A cpu is useless without ram.  My original approach was to use
block ram to create a ROM to store the main program files. and then
to use block ram for general purpose ram to store the stack and heap stuff.
When it came down to synthesis, I found that I only had enough block ram
for the rom.  I had two options, buy a bigger machine, or use micron's block ram.
It took a large sum of time to figure out how to use it, but in the end it paid off.

Remember that this is a guide in using asynchronous mode.  Its slower, but it makes everything
more homogenous.  And since I'm using it as a ram, I have no idea where the cpu is going to set/get the data.

Stuff that you need to make it work:

  1.  spec sheet
    1. They added an extra T to the name, making it harder to find
  2. Spartan 6 on nexus 3
    1. it has enough bram for a 32kx16 rom.  If you have a bigger board then you probably don't need to use the micron cellular ram.
  3. A guide for asynchronous mode
    1. pay attention to only slides 13,14, 21, and 22
  4. xilinx (i used version 14, but other versions should still work)

Gotchas

  1. You gotta let the device power on before you can use it. see init state in the FSM
  2. The specs say that you can do async read and write in 70 ns.  True, but once you add the commands to start the device up you get closer to 100 ns.
  3. using tristate buffers on the bidirectional dq bus is a must.
  4. The specs brag about the memory running at 80mhz, but that is for burst/page mode which are much harder to use.  Async mode will get you 10mhz.


my FSM

T : timer 10 ns

//These pins are used to talk to the celular ram  (memory_interface <--> cellular_ram);
addr_o : out std_logic_vector( addr_width-1 downto 0);
clk_o : out  std_logic;
addr_valid_o :out std_logic;
cntl_reg_enable_o : out std_logic;
chip_enable_o : out std_logic;
output_enable_o : out std_logic;
write_en_o : out std_logic;
lower_byte_en_o : out std_logic;
upper_byte_en_o : out std_logic;
data_io : inout std_logic_vector( data_width-1 downto 0);
wait_i : in std_logic;
//These are the pins used to help interface the memory as if it were a block ram ( some module <--> memory_interface);
addr_i : in std_logic_vector (addr_width-1 downto 0);
we_i : in std_logic ;
data_i : in std_logic_vector (data_width-1 downto 0);
data_o : out std_logic_vector (data_width-1 downto 0);
clk_i : in std_logic;
go_i : in std_logic //top module should set this to 0.  when ready to use, set to 1 for one cycle (max 90 ns) then bring down.  when go_i is high it will read or write otherwise it will be idle.;

View this high level pic to see where everything falls in place

Code: the stuff you probably just wanna take and play with right out of the box and probably the only thing you care about

memory interface

component used to interact with the memory interface

The two links above are synthesis able.  I linked them together in a wrapper file, loaded them on to the FPGA and crossed my fingers.  The first link goes to the source code for the memory interface.  It lets you use the memory as if it was a block ram.  But be warned....you may only read/write every 100ns.  Any slower will cause unexpected data.  Going slower is pretty much acceptable.  Oh yeah, remember to toggle the go_i input when you want to read/write.

the second link takes you to what looks like a massively long entity.  In actuality it has several architectures.  Each architecture has a different test.  One of them writes to 16k memory arrays one after the other, then reads them one after another.  Another test jumps really far to write and then jumps to read each of them.