You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			199 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			199 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
| #include <stdint.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <stdbool.h>
 | |
| #include <string.h>
 | |
| #include <termios.h>
 | |
| #include <unistd.h>
 | |
| #include <poll.h>
 | |
| 
 | |
| #include "sim_vhpi_c.h"
 | |
| #include "Vlitedram_core.h"
 | |
| #include "verilated_vcd_c.h"
 | |
| 
 | |
| static Vlitedram_core *v;
 | |
| vluint64_t main_time = 0;
 | |
| 
 | |
| #if VM_TRACE
 | |
| VerilatedVcdC *tfp;
 | |
| #endif
 | |
| 
 | |
| static void cleanup(void)
 | |
| {
 | |
| #if VM_TRACE
 | |
| 	if (tfp) {
 | |
| 		tfp->flush();
 | |
| 		tfp->close();
 | |
| 		delete tfp;
 | |
| 	}
 | |
| #endif
 | |
| }
 | |
| 
 | |
| static inline void check_init(bool traces)
 | |
| {
 | |
| 	if (v)
 | |
| 		return;
 | |
| 	// XX Catch exceptions ?
 | |
| 	v = new Vlitedram_core;
 | |
| 	if (!v) {
 | |
| 		fprintf(stderr, "Failure allocating litedram core\n");
 | |
| 		exit(1);
 | |
| 	}
 | |
| #if VM_TRACE
 | |
| 	if (traces) {
 | |
| 		// init trace dump
 | |
| 		Verilated::traceEverOn(true);
 | |
| 		tfp = new VerilatedVcdC;
 | |
| 		v->trace(tfp, 99);
 | |
| 		tfp->open("litedram.vcd");
 | |
| 	}
 | |
| #endif
 | |
| 	atexit(cleanup);
 | |
| }
 | |
| 
 | |
| unsigned char get_bit(unsigned char **p)
 | |
| {
 | |
| 	unsigned char b = **p;
 | |
| 
 | |
| 	*p = *p + 1;
 | |
| 
 | |
| 	return b  == vhpi1 ? 1  : 0;
 | |
| }
 | |
| 
 | |
| uint64_t get_bits(unsigned char **p, int len)
 | |
| {
 | |
| 	uint64_t r = 0;
 | |
| 
 | |
| 	while(len--)
 | |
| 		r = (r << 1) | get_bit(p);
 | |
| 	
 | |
| 	return r;
 | |
| }
 | |
| 
 | |
| void set_bit(unsigned char **p, int bit)
 | |
| {
 | |
| 	**p = bit ? vhpi1 : vhpi0;
 | |
| 	*p = *p + 1;
 | |
| }
 | |
| 
 | |
| void set_bits(unsigned char **p, uint64_t val, int len)
 | |
| {
 | |
| 	while(len--)
 | |
| 		set_bit(p, (val >> len) & 1);
 | |
| }
 | |
| 
 | |
| double sc_time_stamp(void)
 | |
| {
 | |
| 	return main_time;
 | |
| }
 | |
| 
 | |
| #define check_size(s, exp)						\
 | |
| 	do {								\
 | |
| 		int __s = (s);						\
 | |
| 		int __e = (exp);					\
 | |
| 		if (__s != __e)						\
 | |
| 			fprintf(stderr, "WARNING: %s exp %d got %d\n", __func__, __e, __s); \
 | |
| 	} while(0)
 | |
| 
 | |
| static void do_eval(void)
 | |
| {
 | |
| 	v->eval();
 | |
| #if VM_TRACE
 | |
| 	if (tfp)
 | |
| 		tfp->dump((double) main_time);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| extern "C" void litedram_set_wb(unsigned char *req)
 | |
| {
 | |
| 	unsigned char *orig = req;
 | |
| 
 | |
| 	check_init(false);
 | |
| 	
 | |
| 	v->wb_ctrl_cti   = get_bits(&req, 3);
 | |
| 	v->wb_ctrl_bte   = get_bits(&req, 2);
 | |
| 	v->wb_ctrl_sel   = get_bits(&req, 4);
 | |
| 	v->wb_ctrl_we    = get_bit(&req);
 | |
| 	v->wb_ctrl_stb   = get_bit(&req);
 | |
| 	v->wb_ctrl_cyc   = get_bit(&req);
 | |
| 	v->wb_ctrl_adr   = get_bits(&req, 30);
 | |
| 	v->wb_ctrl_dat_w = get_bits(&req, 32);
 | |
| 
 | |
| 	check_size(req - orig, 74);
 | |
| 
 | |
| 	do_eval();
 | |
| }
 | |
| 
 | |
| extern "C" void litedram_get_wb(unsigned char *req)
 | |
| {
 | |
| 	unsigned char *orig = req;
 | |
| 
 | |
| 	check_init(false);
 | |
| 
 | |
| 	set_bit(&req, v->init_error);
 | |
| 	set_bit(&req, v->init_done);
 | |
| 	set_bit(&req, v->wb_ctrl_err);
 | |
| 	set_bit(&req, v->wb_ctrl_ack);
 | |
| 	set_bits(&req, v->wb_ctrl_dat_r, 32);
 | |
| 
 | |
| 	check_size(req - orig, 36);
 | |
| }
 | |
| 
 | |
| extern "C" void litedram_set_user(unsigned char *req)
 | |
| {
 | |
| 	unsigned char *orig = req;
 | |
| 
 | |
| 	check_init(false);
 | |
| 
 | |
| 	v->user_port_native_0_cmd_valid     = get_bit(&req);
 | |
| 	v->user_port_native_0_cmd_we        = get_bit(&req);
 | |
| 	v->user_port_native_0_wdata_valid   = get_bit(&req);
 | |
| 	v->user_port_native_0_rdata_ready   = get_bit(&req);
 | |
| 	v->user_port_native_0_cmd_addr      = get_bits(&req, 24);
 | |
| 	v->user_port_native_0_wdata_we      = get_bits(&req, 16);
 | |
| 	v->user_port_native_0_wdata_data[3] = get_bits(&req, 32);
 | |
| 	v->user_port_native_0_wdata_data[2] = get_bits(&req, 32);
 | |
| 	v->user_port_native_0_wdata_data[1] = get_bits(&req, 32);
 | |
| 	v->user_port_native_0_wdata_data[0] = get_bits(&req, 32);
 | |
| 
 | |
| 	check_size(req - orig, 172);
 | |
| 
 | |
| 	do_eval();
 | |
| }
 | |
| 
 | |
| extern "C" void litedram_get_user(unsigned char *req)
 | |
| {
 | |
| 	unsigned char *orig = req;
 | |
| 
 | |
| 	check_init(false);
 | |
| 
 | |
| 	set_bit(&req, v->user_port_native_0_cmd_ready);
 | |
| 	set_bit(&req, v->user_port_native_0_wdata_ready);
 | |
| 	set_bit(&req, v->user_port_native_0_rdata_valid);
 | |
| 	set_bits(&req, v->user_port_native_0_rdata_data[3], 32);
 | |
| 	set_bits(&req, v->user_port_native_0_rdata_data[2], 32);
 | |
| 	set_bits(&req, v->user_port_native_0_rdata_data[1], 32);
 | |
| 	set_bits(&req, v->user_port_native_0_rdata_data[0], 32);
 | |
| 
 | |
| 	check_size(req - orig, 131);
 | |
| }
 | |
| 
 | |
| extern "C" void litedram_clock(void)
 | |
| {
 | |
| 	check_init(false);
 | |
| 
 | |
| 	v->clk = 1;
 | |
| 	do_eval();
 | |
| 	main_time++;
 | |
| 	v->clk = 0;
 | |
| 	do_eval();
 | |
| 	main_time++;
 | |
| }
 | |
| 
 | |
| extern "C" void litedram_init(int trace_on)
 | |
| {
 | |
| 	check_init(!!trace_on);
 | |
| }
 | |
| 
 | |
| 	
 |