iverilog/vvp/memory.h

181 lines
5.9 KiB
C++

#ifndef __memory_H // -*- c++ -*-
#define __memory_H
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: memory.h,v 1.13 2007/03/22 16:08:19 steve Exp $"
#endif
#include "vvp_net.h"
#include "vpi_user.h"
/*
** vvp_memory_t is a memory
** vvp_memory_index_t is a memory index range definition
*/
typedef struct vvp_memory_s *vvp_memory_t;
struct memory_address_range {
int msb;
int lsb;
};
/*
* Given a memory device, the memory_configure function configures it
* by defining the dimensions of the device. It is an error to
* redefine the dimensions of a device already configured.
*
* The lsb and msb define the dimensions of a word. They are in
* Verilog form. The actual word contents are vvp_vector4_t values.
*
* The idx array is an array of address ranges that describe the
* complete multi-dimensional array. In a normal Verilog array, idxs
* is 1, and idx is a pointer to a single memory_address_range. The
* table does not need to be persistent.
*/
extern void memory_configure(vvp_memory_t mem, int msb, int lsb,
unsigned idxs,
const struct memory_address_range *idx);
extern void memory_attach_self(vvp_memory_t mem, vpiHandle self);
/*
* init_word and set_word functions take the memory to be manipulated
* and write a word value at the given word address. The idx is the
* canonical (0-based, 1-dimensional) address of the word to be
* written. The caller needs to have converted any multi-dimensional
* address into a canonical address first.
*
* The difference between init_word and set_word are that the set_word
* function causes values to be propagated through structural ports,
* but the init_word does not.
*/
extern void memory_init_word(vvp_memory_t mem,
unsigned idx,
vvp_vector4_t val);
extern void memory_set_word(vvp_memory_t mem,
unsigned idx,
unsigned off,
vvp_vector4_t val);
/*
* this doesn't actually write the value to the memory word, but
* scedules for the write to happen some time in the future. The delay
* is in simulation clock units
*/
void schedule_memory(vvp_memory_t mem, unsigned addr,
vvp_vector4_t val, unsigned long delay);
/*
* Get the word value at the given index into the memory.
*/
extern vvp_vector4_t memory_get_word(vvp_memory_t mem, unsigned idx);
/* Number of words in the memory. */
unsigned memory_word_count(vvp_memory_t mem);
/* Width of a word */
unsigned memory_word_width(vvp_memory_t mem);
/* Get the user declared geometry of the memory address. This is the
msb and lsb values for each pair in the multi-dimensional array. */
long memory_left_range(vvp_memory_t mem, unsigned ix);
long memory_right_range(vvp_memory_t mem, unsigned ix);
/* Get the user defined geometry for the memory *word*. */
long memory_word_left_range(vvp_memory_t mem);
long memory_word_right_range(vvp_memory_t mem);
/* vvp_fun_memport
* The vvp_fum_memport is a structural port into a vvp_memory_t
* object. The output is the word that is read from the addressed
* memory, and the inputs are the address and optional write controls.
*
* 0 -- Address
* This addresses the word in the memory. The output follows this
* address as it changes, and also follows the value of the addressed
* word.
*
* 1 -- Write event
*
* 2 -- Write enable
*
* 3 -- Write data
*
* NOTE: This functor is unique in that it needs to store the
* vvp_net_t pointer associated with it. It needs this because it can
* received input from other than its ports. Notably, the memory
* itself reports word changes.
*/
class vvp_fun_memport : public vvp_net_fun_t {
public:
explicit vvp_fun_memport(vvp_memory_t mem, vvp_net_t*net);
~vvp_fun_memport();
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
private:
vvp_memory_t mem_;
friend void memory_set_word(vvp_memory_t, unsigned,
unsigned, vvp_vector4_t);
void check_word_change(unsigned long address);
class vvp_fun_memport*next_;
unsigned long addr_;
vvp_net_t*net_;
};
/*
** Access to the memory symbol table.
**
** The memory_find function locates the memory device by name. If the
** device does not exist, a nil is returned.
**
** The memory_create functio create a new memory device with the given
** name. It is a fatal error to try to create a device that already exists.
*/
vvp_memory_t memory_find(char *label);
vvp_memory_t memory_create(char *label);
/*
* $Log: memory.h,v $
* Revision 1.13 2007/03/22 16:08:19 steve
* Spelling fixes from Larry
*
* Revision 1.12 2006/03/05 05:45:58 steve
* Add support for memory value change callbacks.
*
* Revision 1.11 2006/02/02 02:44:00 steve
* Allow part selects of memory words in l-values.
*
* Revision 1.10 2005/06/22 00:04:49 steve
* Reduce vvp_vector4 copies by using const references.
*
* Revision 1.9 2005/03/09 04:52:40 steve
* reimplement memory ports.
*
* Revision 1.8 2005/03/03 04:33:10 steve
* Rearrange how memories are supported as vvp_vector4 arrays.
*
*/
#endif