mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-27 12:21:57 +00:00
123 lines
3.5 KiB
Verilog
123 lines
3.5 KiB
Verilog
// Author: Dmitry Tselikov http://bashkiria-2m.narod.ru/
|
|
//
|
|
// Modified for b2m: Ivan Gorodetsky
|
|
|
|
|
|
module SDRAM_Controller(
|
|
input clk100, // Clock 100MHz
|
|
input reset, // System reset
|
|
inout [15:0] DRAM_DQ, // SDRAM Data bus 16 Bits
|
|
output reg[12:0] DRAM_ADDR, // SDRAM Address bus 12 Bits
|
|
output reg DRAM_LDQM, // SDRAM Low-byte Data Mask
|
|
output reg 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,
|
|
input ub_n,
|
|
input lb_n,
|
|
output reg memvidbusy,
|
|
output reg memcpubusy,
|
|
input rdv
|
|
);
|
|
|
|
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;
|
|
parameter ST_REFRESH2 = 4'd13;
|
|
parameter ST_REFRESH3 = 4'd14;
|
|
|
|
reg[3:0] state;
|
|
reg[21:0] addr;
|
|
reg[15:0] data;
|
|
reg exrd,exwen;
|
|
reg ubn,lbn,rdvid;
|
|
|
|
assign DRAM_DQ[7:0] = (state==ST_WRITE0) ? data[7:0] : 8'bZZZZZZZZ;
|
|
assign DRAM_DQ[15:8] = (state == ST_WRITE0) ? data[7:0] : 8'bZZZZZZZZ;
|
|
assign DRAM_CS_N = 1'b0;
|
|
assign DRAM_BA_0 = addr[20];
|
|
assign DRAM_BA_1 = addr[21];
|
|
|
|
always @(*) begin
|
|
case (state)
|
|
ST_RESET0: DRAM_ADDR = 13'b100000;
|
|
ST_RAS0: DRAM_ADDR = addr[20:8];
|
|
default: DRAM_ADDR = {5'b00100,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,DRAM_UDQM,DRAM_LDQM} = 5'b10100;
|
|
ST_WRITE0: {DRAM_RAS_N,DRAM_CAS_N,DRAM_WE_N,DRAM_UDQM,DRAM_LDQM} = {3'b100,ubn,lbn};
|
|
ST_WRITE2: {DRAM_UDQM,DRAM_LDQM} = 2'b00;
|
|
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 clk100) begin
|
|
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:
|
|
begin
|
|
if(rdv==0) begin exrd <= rd; exwen <= we_n; end
|
|
addr <= iaddr; data <= idata;
|
|
ubn<=ub_n;lbn<=lb_n;rdvid<=rdv;
|
|
{memcpubusy,memvidbusy}<=2'b00;
|
|
casex ({rd,exrd,we_n,exwen,rdv})
|
|
5'b10110: {state,memcpubusy} <= {ST_RAS0,1'b1};
|
|
5'b00010: {state,memcpubusy} <= {ST_RAS0,1'b1};
|
|
5'bxxxx1: {state,memvidbusy} <= {ST_RAS0,1'b1};
|
|
default: state <= ST_IDLE;
|
|
endcase
|
|
end
|
|
ST_RAS0: state <= ST_RAS1;
|
|
ST_RAS1:
|
|
casex ({exrd,exwen,rdvid})
|
|
3'b110: state <= ST_READ0;
|
|
3'b000: state <= ST_WRITE0;
|
|
3'bxx1: state <= ST_READ0;
|
|
default: state <= ST_IDLE;
|
|
endcase
|
|
ST_READ0: state <= ST_READ1;
|
|
ST_READ1: state <= ST_READ2;
|
|
ST_READ2: case (rdvid)
|
|
1'b0: {state,odata[7:0]} <= {ST_IDLE,lbn?DRAM_DQ[15:8]:DRAM_DQ[7:0]};
|
|
1'b1: {state,odata[15:0]} <= {ST_REFRESH0,DRAM_DQ[15:0]};
|
|
endcase
|
|
ST_WRITE0: state <= ST_WRITE1;
|
|
ST_WRITE1: state <= ST_WRITE2;
|
|
ST_WRITE2: state <= ST_IDLE;
|
|
ST_REFRESH0: state <= ST_REFRESH1;
|
|
ST_REFRESH1: state <= ST_REFRESH2;
|
|
ST_REFRESH2: state <= ST_REFRESH3;
|
|
ST_REFRESH3: state <= ST_IDLE;
|
|
default: state <= ST_IDLE;
|
|
endcase
|
|
end
|
|
end
|
|
|
|
endmodule
|