/* SDRAM Controller A3V64S40ETP 1M Words x 16 bits x 4 Banks (64Mbit) */ declare sdram16_ctrl { output CSn, RASn, CASn, WEn; output LDM, HDM; output DEn; // Write data output enable output BA[2], A[12]; output Din[16]; input Dout[16]; input din[16], adrs[22]; func_in write(adrs, din); func_in read(adrs); output dout[16], ack; output err; } module sdram16_ctrl { reg err_reg = 0b0; reg BA_reg[2]; reg A_reg[12]; // reg LDM_reg = 0b1, HDM_reg = 0b1; reg RASn_reg = 0b1, CASn_reg = 0b1, WEn_reg = 0b1, DEn_reg = 0b1; reg reset = 0b1; reg init_count[16] = 0; // use <14> reg adrs_reg[22], dout_reg[16], din_reg[16]; func_self com_NOP, com_PRE, com_REF, com_MRS, com_ACT, com_WRITE, com_READ; proc_name init; proc_name write_proc(adrs_reg, din_reg); proc_name read_proc(adrs_reg); proc_name refresh_cnt; proc_name refresh; if(reset){ init(); reset := 0b0; } ack = ~(init | read_proc | write_proc); CSn = 0b0; LDM = 0b0; // LDM_reg; HDM = 0b0; // HDM_reg; RASn = RASn_reg; CASn = CASn_reg; WEn = WEn_reg; DEn = DEn_reg; BA = BA_reg; A = A_reg; Din = din_reg; dout = dout_reg; init_count++; func com_NOP { RASn_reg := 0b1; CASn_reg := 0b1; WEn_reg := 0b1; } func com_PRE { RASn_reg := 0b0; CASn_reg := 0b1; WEn_reg := 0b0; } func com_REF { RASn_reg := 0b0; CASn_reg := 0b0; WEn_reg := 0b1; } func com_MRS { RASn_reg := 0b0; CASn_reg := 0b0; WEn_reg := 0b0; } func com_ACT { RASn_reg := 0b0; CASn_reg := 0b1; WEn_reg := 0b1; } func com_WRITE { RASn_reg := 0b1; CASn_reg := 0b0; WEn_reg := 0b0; } func com_READ { RASn_reg := 0b1; CASn_reg := 0b0; WEn_reg := 0b1; } proc init seq{ reg count[6] = 0; label_name iPON, iPALLw, iREF, iMRSw; iPON: { com_NOP(); if(~init_count[14]) goto iPON; } { com_PRE(); A_reg := 0b010000000000; // All banks } iPALLw: { com_NOP(); count++; if(~&count[5:0]) goto iPALLw; } iREF: { count++; if(count[2:0]==0b000) com_REF(); else com_NOP(); if(~&count[5:0]) goto iREF; } com_NOP(); { com_MRS(); BA_reg := 0b00; A_reg := {0b00000, 0b010, 0b0000}; // CAS 2 Burst 1 } iMRSw: { com_NOP(); count++; if(~count[3]) goto iMRSw; else{ refresh_cnt(); finish; } } } func write write_proc(adrs, din); proc write_proc seq{ label_name ACT; ACT: if(~refresh){ com_ACT(); BA_reg := adrs_reg[21:20]; A_reg := adrs_reg[19:8]; DEn_reg := 0b0; } else goto ACT; { com_WRITE(); A_reg := {0b0100, adrs_reg[7:0]}; // Auto Precharge } { com_NOP(); DEn_reg := 0b1; finish; } } func read read_proc(adrs); proc read_proc seq{ label_name ACT; ACT: if(~refresh){ com_ACT(); BA_reg := adrs_reg[21:20]; A_reg := adrs_reg[19:8]; } else goto ACT; { com_READ(); A_reg := {0b0100, adrs_reg[7:0]}; // Auto Precharge } com_NOP(); com_NOP(); { // CL 2 dout_reg := Dout; finish; } } proc refresh_cnt seq{ reg refresh_time[7] = 0; label_name cf_count, cf_refresh; cf_count: { refresh_time++; if(~&refresh_time) goto cf_count; } cf_refresh: if(~(read_proc | write_proc)){ refresh(); finish; } else goto cf_refresh; } proc refresh seq{ reg refresh_A[14] = 0; { com_ACT(); BA_reg := refresh_A[1:0]; A_reg := refresh_A[13:2]; } { com_PRE(); A_reg := 0b010000000000; refresh_A++; } { com_NOP(); refresh_cnt(); finish; } } }