Line 1... |
Line 1... |
//
|
//
|
// ram.v -- main memory, using SDRAM
|
// ram.v -- external RAM interface, using SDRAM
|
|
// 8M x 32 bit = 32 MB
|
//
|
//
|
|
|
|
|
module ram(clk, clk_ok, reset,
|
`timescale 1ns/10ps
|
en, wr, size, addr,
|
`default_nettype none
|
data_in, data_out, wt,
|
|
|
|
|
module ram(clk, clk_ok, rst,
|
|
stb, we, addr,
|
|
data_in, data_out, ack,
|
sdram_cke, sdram_cs_n,
|
sdram_cke, sdram_cs_n,
|
sdram_ras_n, sdram_cas_n,
|
sdram_ras_n, sdram_cas_n,
|
sdram_we_n, sdram_ba, sdram_a,
|
sdram_we_n, sdram_ba, sdram_a,
|
sdram_udqm, sdram_ldqm, sdram_dq);
|
sdram_udqm, sdram_ldqm, sdram_dq);
|
// internal interface signals
|
// internal interface signals
|
input clk;
|
input clk;
|
input clk_ok;
|
input clk_ok;
|
input reset;
|
input rst;
|
input en;
|
input stb;
|
input wr;
|
input we;
|
input [1:0] size;
|
input [24:2] addr;
|
input [24:0] addr;
|
|
input [31:0] data_in;
|
input [31:0] data_in;
|
output reg [31:0] data_out;
|
output reg [31:0] data_out;
|
output reg wt;
|
output reg ack;
|
// SDRAM interface signals
|
// SDRAM interface signals
|
output sdram_cke;
|
output sdram_cke;
|
output sdram_cs_n;
|
output sdram_cs_n;
|
output sdram_ras_n;
|
output sdram_ras_n;
|
output sdram_cas_n;
|
output sdram_cas_n;
|
Line 31... |
Line 35... |
output [12:0] sdram_a;
|
output [12:0] sdram_a;
|
output sdram_udqm;
|
output sdram_udqm;
|
output sdram_ldqm;
|
output sdram_ldqm;
|
inout [15:0] sdram_dq;
|
inout [15:0] sdram_dq;
|
|
|
reg [3:0] state;
|
reg [2:0] state;
|
reg a0;
|
reg a0;
|
reg cntl_read;
|
reg cntl_read;
|
reg cntl_write;
|
reg cntl_write;
|
wire cntl_done;
|
wire cntl_done;
|
wire [23:0] cntl_addr;
|
wire [23:0] cntl_addr;
|
Line 45... |
Line 49... |
wire sd_out_en;
|
wire sd_out_en;
|
wire [15:0] sd_out;
|
wire [15:0] sd_out;
|
|
|
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
|
|
sdramCntl sdramCntl1(
|
sdramCntl sdramCntl_1(
|
// clock
|
// clock
|
.clk(clk),
|
.clk(clk),
|
.clk_ok(clk_ok),
|
.clk_ok(clk_ok),
|
// host side
|
// host side
|
.rd(cntl_read & ~cntl_done),
|
.rd(cntl_read & ~cntl_done),
|
Line 77... |
Line 81... |
|
|
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
|
|
// the SDRAM is organized in 16-bit halfwords
|
// the SDRAM is organized in 16-bit halfwords
|
// address line 0 is controlled by the state machine
|
// address line 0 is controlled by the state machine
|
// (this is necessary for word accesses)
|
|
assign cntl_addr[23:1] = addr[24:2];
|
assign cntl_addr[23:1] = addr[24:2];
|
assign cntl_addr[0] = a0;
|
assign cntl_addr[0] = a0;
|
|
|
// state machine for SDRAM access
|
// state machine for SDRAM access
|
always @(posedge clk) begin
|
always @(posedge clk) begin
|
if (reset == 1) begin
|
if (rst) begin
|
state <= 4'b0000;
|
state <= 3'b000;
|
wt <= 1;
|
ack <= 0;
|
end else begin
|
end else begin
|
case (state)
|
case (state)
|
4'b0000:
|
3'b000:
|
// wait for access
|
// wait for access
|
begin
|
begin
|
if (en == 1) begin
|
if (stb) begin
|
// access
|
// access
|
if (wr == 1) begin
|
if (we) begin
|
// write
|
// write
|
if (size[1] == 1) begin
|
state <= 3'b001;
|
// write word
|
|
state <= 4'b0001;
|
|
end else begin
|
|
if (size[0] == 1) begin
|
|
// write halfword
|
|
state <= 4'b0101;
|
|
end else begin
|
|
// write byte
|
|
state <= 4'b0111;
|
|
end
|
|
end
|
|
end else begin
|
end else begin
|
// read
|
// read
|
if (size[1] == 1) begin
|
state <= 3'b011;
|
// read word
|
|
state <= 4'b0011;
|
|
end else begin
|
|
if (size[0] == 1) begin
|
|
// read halfword
|
|
state <= 4'b0110;
|
|
end else begin
|
|
// read byte
|
|
state <= 4'b1001;
|
|
end
|
|
end
|
|
end
|
end
|
end
|
end
|
end
|
end
|
4'b0001:
|
3'b001:
|
// write word, upper 16 bits
|
// write word, upper 16 bits
|
begin
|
begin
|
if (cntl_done == 1) begin
|
if (cntl_done) begin
|
state <= 4'b0010;
|
state <= 3'b010;
|
end
|
end
|
end
|
end
|
4'b0010:
|
3'b010:
|
// write word, lower 16 bits
|
// write word, lower 16 bits
|
begin
|
begin
|
if (cntl_done == 1) begin
|
if (cntl_done) begin
|
state <= 4'b1111;
|
state <= 3'b111;
|
wt <= 0;
|
ack <= 1;
|
end
|
end
|
end
|
end
|
4'b0011:
|
3'b011:
|
// read word, upper 16 bits
|
// read word, upper 16 bits
|
begin
|
begin
|
if (cntl_done == 1) begin
|
if (cntl_done) begin
|
state <= 4'b0100;
|
state <= 3'b100;
|
data_out[31:16] <= cntl_dout;
|
data_out[31:16] <= cntl_dout;
|
end
|
end
|
end
|
end
|
4'b0100:
|
3'b100:
|
// read word, lower 16 bits
|
// read word, lower 16 bits
|
begin
|
begin
|
if (cntl_done == 1) begin
|
if (cntl_done) begin
|
state <= 4'b1111;
|
state <= 3'b111;
|
data_out[15:0] <= cntl_dout;
|
|
wt <= 0;
|
|
end
|
|
end
|
|
4'b0101:
|
|
// write halfword
|
|
begin
|
|
if (cntl_done == 1) begin
|
|
state <= 4'b1111;
|
|
wt <= 0;
|
|
end
|
|
end
|
|
4'b0110:
|
|
// read halfword
|
|
begin
|
|
if (cntl_done == 1) begin
|
|
state <= 4'b1111;
|
|
data_out[31:16] <= 16'h0000;
|
|
data_out[15:0] <= cntl_dout;
|
data_out[15:0] <= cntl_dout;
|
wt <= 0;
|
ack <= 1;
|
end
|
|
end
|
|
4'b0111:
|
|
// write byte (read halfword cycle)
|
|
begin
|
|
if (cntl_done == 1) begin
|
|
state <= 4'b1000;
|
|
data_out[31:16] <= 16'h0000;
|
|
data_out[15:0] <= cntl_dout;
|
|
end
|
|
end
|
|
4'b1000:
|
|
// write byte (write halfword cycle)
|
|
begin
|
|
if (cntl_done == 1) begin
|
|
state <= 4'b1111;
|
|
wt <= 0;
|
|
end
|
|
end
|
|
4'b1001:
|
|
// read byte
|
|
begin
|
|
if (cntl_done == 1) begin
|
|
state <= 4'b1111;
|
|
data_out[31:8] <= 24'h000000;
|
|
if (addr[0] == 0) begin
|
|
data_out[7:0] <= cntl_dout[15:8];
|
|
end else begin
|
|
data_out[7:0] <= cntl_dout[7:0];
|
|
end
|
|
wt <= 0;
|
|
end
|
end
|
end
|
end
|
4'b1111:
|
3'b111:
|
// end of bus cycle
|
// end of bus cycle
|
begin
|
begin
|
state <= 4'b0000;
|
state <= 3'b000;
|
wt <= 1;
|
ack <= 0;
|
end
|
end
|
default:
|
default:
|
// all other states: reset
|
// all other states: reset
|
begin
|
begin
|
state <= 4'b0000;
|
state <= 3'b000;
|
wt <= 1;
|
ack <= 0;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
// output of state machine
|
// output of state machine
|
always @(*) begin
|
always @(*) begin
|
case (state)
|
case (state)
|
4'b0000:
|
3'b000:
|
// wait for access
|
// wait for access
|
begin
|
begin
|
a0 = 1'bx;
|
a0 = 1'bx;
|
cntl_read = 0;
|
cntl_read = 0;
|
cntl_write = 0;
|
cntl_write = 0;
|
cntl_din = 16'hxxxx;
|
cntl_din = 16'hxxxx;
|
end
|
end
|
4'b0001:
|
3'b001:
|
// write word, upper 16 bits
|
// write word, upper 16 bits
|
begin
|
begin
|
a0 = 1'b0;
|
a0 = 1'b0;
|
cntl_read = 0;
|
cntl_read = 0;
|
cntl_write = 1;
|
cntl_write = 1;
|
cntl_din = data_in[31:16];
|
cntl_din = data_in[31:16];
|
end
|
end
|
4'b0010:
|
3'b010:
|
// write word, lower 16 bits
|
// write word, lower 16 bits
|
begin
|
begin
|
a0 = 1'b1;
|
a0 = 1'b1;
|
cntl_read = 0;
|
cntl_read = 0;
|
cntl_write = 1;
|
cntl_write = 1;
|
cntl_din = data_in[15:0];
|
cntl_din = data_in[15:0];
|
end
|
end
|
4'b0011:
|
3'b011:
|
// read word, upper 16 bits
|
// read word, upper 16 bits
|
begin
|
begin
|
a0 = 1'b0;
|
a0 = 1'b0;
|
cntl_read = 1;
|
cntl_read = 1;
|
cntl_write = 0;
|
cntl_write = 0;
|
cntl_din = 16'hxxxx;
|
cntl_din = 16'hxxxx;
|
end
|
end
|
4'b0100:
|
3'b100:
|
// read word, lower 16 bits
|
// read word, lower 16 bits
|
begin
|
begin
|
a0 = 1'b1;
|
a0 = 1'b1;
|
cntl_read = 1;
|
cntl_read = 1;
|
cntl_write = 0;
|
cntl_write = 0;
|
cntl_din = 16'hxxxx;
|
cntl_din = 16'hxxxx;
|
end
|
end
|
4'b0101:
|
3'b111:
|
// write halfword
|
|
begin
|
|
a0 = addr[1];
|
|
cntl_read = 0;
|
|
cntl_write = 1;
|
|
cntl_din = data_in[15:0];
|
|
end
|
|
4'b0110:
|
|
// read halfword
|
|
begin
|
|
a0 = addr[1];
|
|
cntl_read = 1;
|
|
cntl_write = 0;
|
|
cntl_din = 16'hxxxx;
|
|
end
|
|
4'b0111:
|
|
// write byte (read halfword cycle)
|
|
begin
|
|
a0 = addr[1];
|
|
cntl_read = 1;
|
|
cntl_write = 0;
|
|
cntl_din = 16'hxxxx;
|
|
end
|
|
4'b1000:
|
|
// write byte (write halfword cycle)
|
|
begin
|
|
a0 = addr[1];
|
|
cntl_read = 0;
|
|
cntl_write = 1;
|
|
if (addr[0] == 0) begin
|
|
cntl_din = { data_in[7:0], data_out[7:0] };
|
|
end else begin
|
|
cntl_din = { data_out[15:8], data_in[7:0] };
|
|
end
|
|
end
|
|
4'b1001:
|
|
// read byte
|
|
begin
|
|
a0 = addr[1];
|
|
cntl_read = 1;
|
|
cntl_write = 0;
|
|
cntl_din = 16'hxxxx;
|
|
end
|
|
4'b1111:
|
|
// end of bus cycle
|
// end of bus cycle
|
begin
|
begin
|
a0 = 1'bx;
|
a0 = 1'bx;
|
cntl_read = 0;
|
cntl_read = 0;
|
cntl_write = 0;
|
cntl_write = 0;
|