RISCV模拟器中关于读写存储器部分的实现

本文详细介绍了一种使用C语言实现内存读写的方法,包括文件加载到内存缓冲区、初始化内存、从内存读取指令及不同位宽的数据读写操作。通过对内存缓冲区的精细管理,实现了高效的数据存取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#define BUFF_SIZE 1024*1024*8
#include "stdio.h"

static unsigned int ins_buff[BUFF_SIZE] ; 
static unsigned int len = 0 ;
static unsigned char  RAM_B0[BUFF_SIZE] ; 
static unsigned char RAM_B1[BUFF_SIZE] ; 
static unsigned char RAM_B2[BUFF_SIZE] ; 
static unsigned char RAM_B3[BUFF_SIZE] ;


static int file_2_ins_buff(char *fn){
	int r,i ;	FILE *fp ; 
	fp = fopen( fn , "rb" );	
	if (fp==NULL) printf("can not open file %s\n",fn);
	if (fp==NULL) exit(1);
	r = fread( ins_buff , 1, BUFF_SIZE ,fp );
	fclose (fp);
	len = r>>2;
	//printf("get file size is %d\n", len );
		for( i = 0 ;i<len ;++i ){
             if (debug())printf("%08x : %08x \n",i<<2, ins_buff[i] );
             }
	return r ;	
}

static int init_MEM_by_ins_buff(){
	int i ;
	for( i = 0 ;i<len ;++i ){
    if (debug())      printf("%08x :  ",ins_buff[i] );
	RAM_B0[i] = ins_buff[i] & 0xff ;
	RAM_B1[i] = ins_buff[i]>>8 & 0xff ;
	RAM_B2[i] = ins_buff[i]>>16 & 0xff ;
	RAM_B3[i] = ins_buff[i]>>24 & 0xff ; 
    if (debug())printf("%08x : %02x  %02x  %02x  %02x \n",i<<2,RAM_B3[i],RAM_B2[i],RAM_B1[i],RAM_B0[i]);	
	}
}

int load_prog(char *fn )  {
    file_2_ins_buff(fn) ; 
    init_MEM_by_ins_buff();
}
 
unsigned int get_ins(unsigned int PC){
unsigned int t;
unsigned char a[4] ; 
	t =PC >>2 ;
	a[3] = RAM_B3[t];
	a[2] = RAM_B2[t];
	a[1] = RAM_B1[t];
	a[0] = RAM_B0[t];
	t=a[3];t<<=8;
	t|=a[2];t<<=8;
	t|=a[1];t<<=8;
	t|=a[0];	
	return t;	
} 

unsigned int read_memory_8bit(unsigned int addr){
	unsigned  int addr32,idx;
	addr32  =  addr >>2 ;
	idx = addr % 4 ;
	if      (idx==0) return RAM_B0[addr32];
	else if (idx==1) return RAM_B1[addr32];
	else if (idx==2) return RAM_B2[addr32];
	else if (idx==3) return RAM_B3[addr32];
}

void write_memory_8bit (unsigned int val,unsigned int addr){
	unsigned char d8  ;
	unsigned  int addr32,idx;
	addr32  =  addr >> 2 ;
	idx = addr % 4 ;
	d8 = val &0xff ;
    if      (idx==0) { RAM_B0[addr32] = d8; } 
	else if (idx==1) { RAM_B1[addr32] = d8; }
	else if (idx==2) { RAM_B2[addr32] = d8; }
	else if (idx==3) { RAM_B3[addr32] = d8; }
//         printf("                                                 U8 IO WR: %08x ,%08x\n",addr,val);	
}



unsigned int read_memory_16bit(unsigned int addr){
	unsigned  int addr32,idx;
	unsigned char hi,lo;
	unsigned int r ; 
	addr32  =  addr >>2;
	idx = addr % 4 ;
	if      (idx==0) { hi = RAM_B1[addr32] ;lo =  RAM_B0[addr32]; }
	else if (idx==2) { hi = RAM_B3[addr32] ;lo =  RAM_B2[addr32] ; };
	r = hi ;	r<<=8;	r|=lo;
	return r ;
}

void write_memory_16bit (unsigned int val,unsigned int addr){
	unsigned  int addr32,idx;
	unsigned char hi,lo;
	unsigned int r ; 
	lo = val & 0xff;	val >>= 8 ;	hi = val& 0xff ;	addr32  =  addr >>2 ;	idx = addr % 4 ;
	if      (idx==0) { RAM_B1[addr32] = hi ; RAM_B0[addr32] = lo ;}
	else if (idx==2)  { RAM_B3[addr32] = hi ; RAM_B2[addr32] = lo ;}
      //   printf("                                                 U16 IO WR: %08x ,%08x\n",addr,val);
	return   ;
}




unsigned int read_memory_32bit(unsigned int addr){
	unsigned  int addr32,idx; 
	unsigned int r ; 
	addr32  =  addr >> 2; 
	r = RAM_B3[addr32];r<<=8;
	r |= RAM_B2[addr32];r<<=8;
	r |= RAM_B1[addr32];r<<=8;
	r |= RAM_B0[addr32]; 
if (debug())	printf("read memory[ %08x ]= %08x \n",addr,r);
	return r ;
}

void write_memory_32bit (unsigned int val,unsigned int addr){
	unsigned  int addr32,idx; 
	unsigned int t ; 
	if (addr <= (BUFF_SIZE >>2))
    {
	addr32  =  addr >> 2; 
	t = val ;
	RAM_B0[addr32] = t &0xff ; t>>=8;
	RAM_B1[addr32] = t &0xff ; t>>=8;
	RAM_B2[addr32] = t &0xff ; t>>=8;
    RAM_B3[addr32] = t &0xff ;
    }
    else 
    {
		 printf("%c",(char )(val&0xff)); 
    }
	return ;	
} 

其中处理器读写存储器部部分在之前文章有详细分析,现在相当于是C语言版本。

实验目的: (1)掌握 RISC-V 指令集 RV32I 典型指令的硬件实现 (2)实现 ALU 功能扩展与数据通路优化 实验内容 (1)RISC-V 指令集实现 基于 RV32I 标准,实现 8 条典型指令(R 型:add/slt/sltu;I 型:ori/lw;U 型:lui;S 型:sw;B 型:beq;J 型:jal),覆盖 6 种指令格式,解析指令编码(opcode/funct3/funct7 / 立即数)与功能逻辑。 (2)ALU 功能扩展 支持算术运算(加法)、逻辑或(ori)、有 / 无符号比较(slt/sltu),通过控制信号(aluop)匹配指令操作类型,输出运算结果或比较标志。 (3)数据通路与模块修改 1、译码阶段:提取指令字段(rs1/rs2/rd/ 立即数),生成 inst_o 信号传递至执行阶段。 2、 执行阶段:计算访存地址(lw/sw 的 Addr=rs1 + 符号扩展立即数)、跳转偏移(beq/jal 的 PC 增量),输出 aluop、mem_addr 等控制信号。 3、访存阶段:根据指令类型(lw/sw)控制数据存储器读写,处理加载数据的对齐调整(如 32 位字读取)。 (4)系统结构优化 通过 EX/MEM、MEM/WB 流水线寄存器传递中间结果,确保指令执行各阶段(取指→译码→执行→访存→写回)信号同步,支持 PC 跳转(beq 条件满足、jal 直接跳转)与寄存器写回(rd 目标寄存器)。 (5)仿真验证 运行脚本,调试波形验证指令执行时序,确认 PC 更新、寄存器数据、存储器访问及跳转逻辑符合 RV32I 规范
06-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值