emulador de ram estática con memoria sdram

Diseño HDL con este lenguaje. Módulos y testbenchs. Estilos y trucos de codificación, etc. NOTA: dado que hay entornos como ISE que soportan Verilog pero no SystemVerilog, señalad dentro de un post que de lo que se va a tratar es SystemVerilog si es el caso.
Responder
Subcritical
GAL
Mensajes: 81
Registrado: 24 Ago 2018, 14:52

emulador de ram estática con memoria sdram

Mensaje por Subcritical » 27 Abr 2019, 09:41

Viendo códigos de cores me he encontrado con este "emulador de memoria sram"

Código: Seleccionar todo

//
// sdram.v
//
// sdram controller implementation for the MiST board
// http://code.google.com/p/mist-board/
// 
// Copyright (c) 2013 Till Harbaum <till@harbaum.org> 
// 
// This source file is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published 
// by the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
// 
// This source file 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, see <http://www.gnu.org/licenses/>. 
//

module sdram (

	// interface to the MT48LC16M16 chip
	output [12:0]		sd_addr,    // 13 bit multiplexed address bus
	inout  reg [15:0]	sd_data,
	output [1:0] 		sd_ba,      // two banks
	output 				sd_cs,      // a single chip select
	output 				sd_we,      // write enable
	output 				sd_ras,     // row address select
	output 				sd_cas,     // columns address select

	// cpu/chipset interface
	input 		 		init,			// init signal after FPGA config to initialize RAM
	input 		 		clk,			// sdram is accessed at up to 128MHz
	
	input [24:0]   	addr,       // 25 bit byte address
	input  [ 7:0]   	din,
	output [ 7:0]  	dout,
	
	input 		 		refresh,    // refresh cycle
	input 		 		ce,         // cpu/chipset access
	input 		 		we          // cpu/chipset requests write
);

// no burst configured
localparam RASCAS_DELAY   = 3'd2;   // tRCD>=20ns -> 2 cycles@64MHz
localparam BURST_LENGTH   = 3'b000; // 000=none, 001=2, 010=4, 011=8
localparam ACCESS_TYPE    = 1'b0;   // 0=sequential, 1=interleaved
localparam CAS_LATENCY    = 3'd2;   // 2/3 allowed
localparam OP_MODE        = 2'b00;  // only 00 (standard operation) allowed
localparam NO_WRITE_BURST = 1'b1;   // 0= write burst enabled, 1=only single access write

localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH}; 

// ---------------------------------------------------------------------
// ------------------------ cycle state machine ------------------------
// ---------------------------------------------------------------------

localparam STATE_IDLE      = 3'd0;   // first state in cycle
localparam STATE_CMD_START = 3'd1;   // state in which a new command can be started
localparam STATE_CMD_CONT  = STATE_CMD_START  + RASCAS_DELAY - 3'd1; // 4 command can be continued
localparam STATE_LAST      = 3'd7;   // last state in cycle

reg [2:0] q /* synthesis noprune */;
reg last_ce, last_refresh;
always @(posedge clk) begin
	last_ce <= ce;
	last_refresh <= refresh;

	// start a new cycle in rising edge of ce or refresh
	if((ce && !last_ce) || (refresh && !last_refresh))
		q <= 3'd1;
	
	if(q != 0)
			q <= q + 3'd1;
end

// ---------------------------------------------------------------------
// --------------------------- startup/reset ---------------------------
// ---------------------------------------------------------------------

// wait 1ms (32 clkref cycles) after FPGA config is done before going
// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0)
reg [4:0] reset;
always @(posedge clk) begin
	if(init)	reset <= 5'h1f;
	else if((q == STATE_LAST) && (reset != 0))
		reset <= reset - 5'd1;
end

// ---------------------------------------------------------------------
// ------------------ generate ram control signals ---------------------
// ---------------------------------------------------------------------

// all possible commands
localparam CMD_INHIBIT         = 4'b1111;
localparam CMD_NOP             = 4'b0111;
localparam CMD_ACTIVE          = 4'b0011;
localparam CMD_READ            = 4'b0101;
localparam CMD_WRITE           = 4'b0100;
localparam CMD_BURST_TERMINATE = 4'b0110;
localparam CMD_PRECHARGE       = 4'b0010;
localparam CMD_AUTO_REFRESH    = 4'b0001;
localparam CMD_LOAD_MODE       = 4'b0000;

reg [3:0] sd_cmd;   // current command sent to sd ram

// drive control signals according to current command
assign sd_cs  = sd_cmd[3];
assign sd_ras = sd_cmd[2];
assign sd_cas = sd_cmd[1];
assign sd_we  = sd_cmd[0];

assign dout = sd_data[7:0];

always @(posedge clk) begin
	sd_cmd <= CMD_INHIBIT;
	sd_data <= we?{din, din}:16'bZZZZZZZZZZZZZZZZ;

	if(reset != 0) begin
		if(q == STATE_IDLE) begin
			if(reset == 13)  sd_cmd <= CMD_PRECHARGE;
			if(reset ==  2)  sd_cmd <= CMD_LOAD_MODE;
		end
	end else begin
		if(q == STATE_IDLE) begin
			if(ce && !last_ce)           sd_cmd <= CMD_ACTIVE;
			if(refresh && !last_refresh) sd_cmd <= CMD_AUTO_REFRESH;
		end else if((q == STATE_CMD_CONT)&&(!refresh)) begin
			if(we)		 sd_cmd <= CMD_WRITE;
			else if(ce)  sd_cmd <= CMD_READ;
		end
	end
end
	
wire [12:0] reset_addr = (reset == 13)?13'b0010000000000:MODE;
	
wire [12:0] run_addr = 
	(q == STATE_CMD_START)?addr[20:8]:{ 4'b0010, addr[23], addr[7:0]};

assign sd_addr = (reset != 0)?reset_addr:run_addr;
assign sd_ba = addr[22:21];

endmodule
sdram.v
(5.04 KiB) Descargado 13 veces

Subcritical
GAL
Mensajes: 81
Registrado: 24 Ago 2018, 14:52

Re: emulador de ram estática con memoria sdram

Mensaje por Subcritical » 27 Abr 2019, 10:05

otro modelo usado en el radio-86rk

Código: Seleccionar todo

module SDRAM_Controller(
	input			clk50mhz,				//  Clock 50MHz
	input			reset,					//  System reset
	inout	[15:0]	DRAM_DQ,				//	SDRAM Data bus 16 Bits
	output	reg[11:0]	DRAM_ADDR,			//	SDRAM Address bus 12 Bits
	output			DRAM_LDQM,				//	SDRAM Low-byte Data Mask 
	output			DRAM_UDQM,				//	SDRAM High-byte Data Mask
	output	reg		DRAM_WE_N,				//	SDRAM Write Enable
	output	reg		DRAM_CAS_N,				//	SDRAM Column Address Strobe
	output	reg		DRAM_RAS_N,				//	SDRAM Row Address Strobe
	output			DRAM_CS_N,				//	SDRAM Chip Select
	output			DRAM_BA_0,				//	SDRAM Bank Address 0
	output			DRAM_BA_1,				//	SDRAM Bank Address 0
	input	[21:0]	iaddr,
	input	[15:0]	idata,
	input			rd,
	input			we_n,
	output	reg [15:0]	odata
);

parameter ST_RESET0 = 4'd0;
parameter ST_RESET1 = 4'd1;
parameter ST_IDLE   = 4'd2;
parameter ST_RAS0   = 4'd3;
parameter ST_RAS1   = 4'd4;
parameter ST_READ0  = 4'd5;
parameter ST_READ1  = 4'd6;
parameter ST_READ2  = 4'd7;
parameter ST_WRITE0 = 4'd8;
parameter ST_WRITE1 = 4'd9;
parameter ST_WRITE2 = 4'd10;
parameter ST_REFRESH0 = 4'd11;
parameter ST_REFRESH1 = 4'd12;

reg[3:0] state;
reg[9:0] refreshcnt;
reg[21:0] addr;
reg[15:0] data;
reg refreshflg,exrd,exwen;

assign DRAM_DQ = state == ST_WRITE0 ? data : 16'bZZZZZZZZZZZZZZZZ;
assign DRAM_LDQM = 0;
assign DRAM_UDQM = 0;
assign DRAM_CS_N = reset;
assign DRAM_BA_0 = addr[20];
assign DRAM_BA_1 = addr[21];

always @(*) begin
	case (state)
	ST_RESET0: DRAM_ADDR = 12'b100000;
	ST_RAS0:   DRAM_ADDR = addr[19:8];
	default:   DRAM_ADDR = {4'b0100,addr[7:0]};
	endcase
	case (state)
	ST_RESET0:   {DRAM_RAS_N,DRAM_CAS_N,DRAM_WE_N} = 3'b000;
	ST_RAS0:     {DRAM_RAS_N,DRAM_CAS_N,DRAM_WE_N} = 3'b011;
	ST_READ0:    {DRAM_RAS_N,DRAM_CAS_N,DRAM_WE_N} = 3'b101;
	ST_WRITE0:   {DRAM_RAS_N,DRAM_CAS_N,DRAM_WE_N} = 3'b100;
	ST_REFRESH0: {DRAM_RAS_N,DRAM_CAS_N,DRAM_WE_N} = 3'b001;
	default:     {DRAM_RAS_N,DRAM_CAS_N,DRAM_WE_N} = 3'b111;
	endcase
end

always @(posedge clk50mhz) begin
	refreshcnt <= refreshcnt + 10'b1;
	if (reset) begin
		state <= ST_RESET0; exrd <= 0; exwen <= 1'b1;
	end else begin
		case (state)
		ST_RESET0: state <= ST_RESET1;
		ST_RESET1: state <= ST_IDLE;
		ST_IDLE: if (refreshcnt[9]!=refreshflg) state <= ST_REFRESH0; else begin
			exrd <= rd; exwen <= we_n; addr <= iaddr; data <= idata;
			casex ({rd,exrd,we_n,exwen})
			4'b1011: state <= ST_RAS0;
			4'b0001: state <= ST_RAS0;
			default: state <= ST_IDLE;
			endcase
		end
		ST_RAS0: state <= ST_RAS1;
		ST_RAS1:
			casex ({exrd,exwen})
			2'b11: state <= ST_READ0;
			2'b00: state <= ST_WRITE0;
			default: state <= ST_IDLE;
			endcase
		ST_READ0: state <= ST_READ1;
		ST_READ1: state <= ST_READ2;
		ST_READ2: {state,odata} <= {ST_IDLE,DRAM_DQ};
		ST_WRITE0: state <= ST_WRITE1;
		ST_WRITE1: state <= ST_WRITE2;
		ST_WRITE2: state <= ST_IDLE;
		ST_REFRESH0: {state,refreshflg} <= {ST_REFRESH1,refreshcnt[9]};
		ST_REFRESH1: state <= ST_IDLE;
		default: state <= ST_IDLE;
		endcase
	end
end
	
endmodule
Descarga:
SDRAM_Controller.v
(2.88 KiB) Descargado 14 veces

Subcritical
GAL
Mensajes: 81
Registrado: 24 Ago 2018, 14:52

Re: emulador de ram estática con memoria sdram

Mensaje por Subcritical » 27 Abr 2019, 11:03


Responder

Volver a “Verilog / SystemVerilog”