aboutsummaryrefslogtreecommitdiffstats
path: root/student_files_2015/student_files_2015/prj2/quartus_proj/DE0_CAMERA/Sdram_Control_4Port/Sdram_Control_4Port.v
diff options
context:
space:
mode:
Diffstat (limited to 'student_files_2015/student_files_2015/prj2/quartus_proj/DE0_CAMERA/Sdram_Control_4Port/Sdram_Control_4Port.v')
-rw-r--r--student_files_2015/student_files_2015/prj2/quartus_proj/DE0_CAMERA/Sdram_Control_4Port/Sdram_Control_4Port.v567
1 files changed, 567 insertions, 0 deletions
diff --git a/student_files_2015/student_files_2015/prj2/quartus_proj/DE0_CAMERA/Sdram_Control_4Port/Sdram_Control_4Port.v b/student_files_2015/student_files_2015/prj2/quartus_proj/DE0_CAMERA/Sdram_Control_4Port/Sdram_Control_4Port.v
new file mode 100644
index 0000000..22e2411
--- /dev/null
+++ b/student_files_2015/student_files_2015/prj2/quartus_proj/DE0_CAMERA/Sdram_Control_4Port/Sdram_Control_4Port.v
@@ -0,0 +1,567 @@
+// --------------------------------------------------------------------
+// Copyright (c) 2008 by Terasic Technologies Inc.
+// --------------------------------------------------------------------
+//
+// Permission:
+//
+// Terasic grants permission to use and modify this code for use
+// in synthesis for all Terasic Development Boards and Altera Development
+// Kits made by Terasic. Other use of this code, including the selling
+// ,duplication, or modification of any portion is strictly prohibited.
+//
+// Disclaimer:
+//
+// This VHDL/Verilog or C/C++ source code is intended as a design reference
+// which illustrates how these types of functions can be implemented.
+// It is the user's responsibility to verify their design for
+// consistency and functionality through the use of formal
+// verification methods. Terasic provides no warranty regarding the use
+// or functionality of this code.
+//
+// --------------------------------------------------------------------
+//
+// Terasic Technologies Inc
+// 356 Fu-Shin E. Rd Sec. 1. JhuBei City,
+// HsinChu County, Taiwan
+// 302
+//
+// web: http://www.terasic.com/
+// email: support@terasic.com
+//
+// --------------------------------------------------------------------
+//
+// Major Functions: Sdram_Control_4Port
+//
+// --------------------------------------------------------------------
+//
+// Revision History :
+// --------------------------------------------------------------------
+// Ver :| Author :| Mod. Date :| Changes Made:
+// V1.0 :| Johnny Fan :| 08/04/22 :| Initial Revision
+// --------------------------------------------------------------------
+
+module Sdram_Control_4Port(
+ // HOST Side
+ REF_CLK,
+ RESET_N,
+ CLK,
+ // FIFO Write Side 1
+ WR1_DATA,
+ WR1,
+ WR1_ADDR,
+ WR1_MAX_ADDR,
+ WR1_LENGTH,
+ WR1_LOAD,
+ WR1_CLK,
+ // FIFO Write Side 2
+ WR2_DATA,
+ WR2,
+ WR2_ADDR,
+ WR2_MAX_ADDR,
+ WR2_LENGTH,
+ WR2_LOAD,
+ WR2_CLK,
+ // FIFO Read Side 1
+ RD1_DATA,
+ RD1,
+ RD1_ADDR,
+ RD1_MAX_ADDR,
+ RD1_LENGTH,
+ RD1_LOAD,
+ RD1_CLK,
+ // FIFO Read Side 2
+ RD2_DATA,
+ RD2,
+ RD2_ADDR,
+ RD2_MAX_ADDR,
+ RD2_LENGTH,
+ RD2_LOAD,
+ RD2_CLK,
+ // SDRAM Side
+ SA,
+ BA,
+ CS_N,
+ CKE,
+ RAS_N,
+ CAS_N,
+ WE_N,
+ DQ,
+ DQM,
+ );
+
+
+`include "Sdram_Params.h"
+// HOST Side
+input REF_CLK; //System Clock
+input RESET_N; //System Reset
+input CLK;
+// FIFO Write Side 1
+input [`DSIZE-1:0] WR1_DATA; //Data input
+input WR1; //Write Request
+input [`ASIZE-1:0] WR1_ADDR; //Write start address
+input [`ASIZE-1:0] WR1_MAX_ADDR; //Write max address
+input [8:0] WR1_LENGTH; //Write length
+input WR1_LOAD; //Write register load & fifo clear
+input WR1_CLK; //Write fifo clock
+
+// FIFO Write Side 2
+input [`DSIZE-1:0] WR2_DATA; //Data input
+input WR2; //Write Request
+input [`ASIZE-1:0] WR2_ADDR; //Write start address
+input [`ASIZE-1:0] WR2_MAX_ADDR; //Write max address
+input [8:0] WR2_LENGTH; //Write length
+input WR2_LOAD; //Write register load & fifo clear
+input WR2_CLK; //Write fifo clock
+
+// FIFO Read Side 1
+output [`DSIZE-1:0] RD1_DATA; //Data output
+input RD1; //Read Request
+input [`ASIZE-1:0] RD1_ADDR; //Read start address
+input [`ASIZE-1:0] RD1_MAX_ADDR; //Read max address
+input [8:0] RD1_LENGTH; //Read length
+input RD1_LOAD; //Read register load & fifo clear
+input RD1_CLK; //Read fifo clock
+
+// FIFO Read Side 2
+output [`DSIZE-1:0] RD2_DATA; //Data output
+input RD2; //Read Request
+input [`ASIZE-1:0] RD2_ADDR; //Read start address
+input [`ASIZE-1:0] RD2_MAX_ADDR; //Read max address
+input [8:0] RD2_LENGTH; //Read length
+input RD2_LOAD; //Read register load & fifo clear
+input RD2_CLK; //Read fifo clock
+
+// SDRAM Side
+output [11:0] SA; //SDRAM address output
+output [1:0] BA; //SDRAM bank address
+output [1:0] CS_N; //SDRAM Chip Selects
+output CKE; //SDRAM clock enable
+output RAS_N; //SDRAM Row address Strobe
+output CAS_N; //SDRAM Column address Strobe
+output WE_N; //SDRAM write enable
+inout [`DSIZE-1:0] DQ; //SDRAM data bus
+output [`DSIZE/8-1:0] DQM; //SDRAM data mask lines
+
+// Internal Registers/Wires
+// Controller
+reg [`ASIZE-1:0] mADDR; //Internal address
+reg [8:0] mLENGTH; //Internal length
+reg [`ASIZE-1:0] rWR1_ADDR; //Register write address
+reg [`ASIZE-1:0] rWR1_MAX_ADDR; //Register max write address
+reg [8:0] rWR1_LENGTH; //Register write length
+reg [`ASIZE-1:0] rWR2_ADDR; //Register write address
+reg [`ASIZE-1:0] rWR2_MAX_ADDR; //Register max write address
+reg [8:0] rWR2_LENGTH; //Register write length
+reg [`ASIZE-1:0] rRD1_ADDR; //Register read address
+reg [`ASIZE-1:0] rRD1_MAX_ADDR; //Register max read address
+reg [8:0] rRD1_LENGTH; //Register read length
+reg [`ASIZE-1:0] rRD2_ADDR; //Register read address
+reg [`ASIZE-1:0] rRD2_MAX_ADDR; //Register max read address
+reg [8:0] rRD2_LENGTH; //Register read length
+reg [1:0] WR_MASK; //Write port active mask
+reg [1:0] RD_MASK; //Read port active mask
+reg mWR_DONE; //Flag write done, 1 pulse SDR_CLK
+reg mRD_DONE; //Flag read done, 1 pulse SDR_CLK
+reg mWR,Pre_WR; //Internal WR edge capture
+reg mRD,Pre_RD; //Internal RD edge capture
+reg [9:0] ST; //Controller status
+reg [1:0] CMD; //Controller command
+reg PM_STOP; //Flag page mode stop
+reg PM_DONE; //Flag page mode done
+reg Read; //Flag read active
+reg Write; //Flag write active
+reg [`DSIZE-1:0] mDATAOUT; //Controller Data output
+wire [`DSIZE-1:0] mDATAIN; //Controller Data input
+wire [`DSIZE-1:0] mDATAIN1; //Controller Data input 1
+wire [`DSIZE-1:0] mDATAIN2; //Controller Data input 2
+wire CMDACK; //Controller command acknowledgement
+// DRAM Control
+reg [`DSIZE/8-1:0] DQM; //SDRAM data mask lines
+reg [11:0] SA; //SDRAM address output
+reg [1:0] BA; //SDRAM bank address
+reg [1:0] CS_N; //SDRAM Chip Selects
+reg CKE; //SDRAM clock enable
+reg RAS_N; //SDRAM Row address Strobe
+reg CAS_N; //SDRAM Column address Strobe
+reg WE_N; //SDRAM write enable
+wire [`DSIZE-1:0] DQOUT; //SDRAM data out link
+wire [`DSIZE/8-1:0] IDQM; //SDRAM data mask lines
+wire [11:0] ISA; //SDRAM address output
+wire [1:0] IBA; //SDRAM bank address
+wire [1:0] ICS_N; //SDRAM Chip Selects
+wire ICKE; //SDRAM clock enable
+wire IRAS_N; //SDRAM Row address Strobe
+wire ICAS_N; //SDRAM Column address Strobe
+wire IWE_N; //SDRAM write enable
+// FIFO Control
+reg OUT_VALID; //Output data request to read side fifo
+reg IN_REQ; //Input data request to write side fifo
+wire [8:0] write_side_fifo_rusedw1;
+wire [8:0] read_side_fifo_wusedw1;
+wire [8:0] write_side_fifo_rusedw2;
+wire [8:0] read_side_fifo_wusedw2;
+// DRAM Internal Control
+wire [`ASIZE-1:0] saddr;
+wire load_mode;
+wire nop;
+wire reada;
+wire writea;
+wire refresh;
+wire precharge;
+wire oe;
+wire ref_ack;
+wire ref_req;
+wire init_req;
+wire cm_ack;
+wire active;
+wire CLK;
+wire CCD_CLK;
+
+control_interface control1 (
+ .CLK(CLK),
+ .RESET_N(RESET_N),
+ .CMD(CMD),
+ .ADDR(mADDR),
+ .REF_ACK(ref_ack),
+ .CM_ACK(cm_ack),
+ .NOP(nop),
+ .READA(reada),
+ .WRITEA(writea),
+ .REFRESH(refresh),
+ .PRECHARGE(precharge),
+ .LOAD_MODE(load_mode),
+ .SADDR(saddr),
+ .REF_REQ(ref_req),
+ .INIT_REQ(init_req),
+ .CMD_ACK(CMDACK)
+ );
+
+command command1(
+ .CLK(CLK),
+ .RESET_N(RESET_N),
+ .SADDR(saddr),
+ .NOP(nop),
+ .READA(reada),
+ .WRITEA(writea),
+ .REFRESH(refresh),
+ .LOAD_MODE(load_mode),
+ .PRECHARGE(precharge),
+ .REF_REQ(ref_req),
+ .INIT_REQ(init_req),
+ .REF_ACK(ref_ack),
+ .CM_ACK(cm_ack),
+ .OE(oe),
+ .PM_STOP(PM_STOP),
+ .PM_DONE(PM_DONE),
+ .SA(ISA),
+ .BA(IBA),
+ .CS_N(ICS_N),
+ .CKE(ICKE),
+ .RAS_N(IRAS_N),
+ .CAS_N(ICAS_N),
+ .WE_N(IWE_N)
+ );
+
+sdr_data_path data_path1(
+ .CLK(CLK),
+ .RESET_N(RESET_N),
+ .DATAIN(mDATAIN),
+ .DM(2'b00),
+ .DQOUT(DQOUT),
+ .DQM(IDQM)
+ );
+
+Sdram_FIFO write_fifo1(
+ .data(WR1_DATA),
+ .wrreq(WR1),
+ .wrclk(WR1_CLK),
+ .aclr(WR1_LOAD),
+ .rdreq(IN_REQ&WR_MASK[0]),
+ .rdclk(CLK),
+ .q(mDATAIN1),
+ .rdusedw(write_side_fifo_rusedw1)
+ );
+
+Sdram_FIFO write_fifo2(
+ .data(WR2_DATA),
+ .wrreq(WR2),
+ .wrclk(WR2_CLK),
+ .aclr(WR2_LOAD),
+ .rdreq(IN_REQ&WR_MASK[1]),
+ .rdclk(CLK),
+ .q(mDATAIN2),
+ .rdusedw(write_side_fifo_rusedw2)
+ );
+
+assign mDATAIN = (WR_MASK[0]) ? mDATAIN1 :
+ mDATAIN2 ;
+
+Sdram_FIFO read_fifo1(
+ .data(mDATAOUT),
+ .wrreq(OUT_VALID&RD_MASK[0]),
+ .wrclk(CLK),
+ .aclr(RD1_LOAD),
+ .rdreq(RD1),
+ .rdclk(RD1_CLK),
+ .q(RD1_DATA),
+ .wrusedw(read_side_fifo_wusedw1)
+ );
+
+Sdram_FIFO read_fifo2(
+ .data(mDATAOUT),
+ .wrreq(OUT_VALID&RD_MASK[1]),
+ .wrclk(CLK),
+ .aclr(RD2_LOAD),
+ .rdreq(RD2),
+ .rdclk(RD2_CLK),
+ .q(RD2_DATA),
+ .wrusedw(read_side_fifo_wusedw2)
+ );
+
+always @(posedge CLK)
+begin
+ SA <= (ST==SC_CL+mLENGTH) ? 12'h200 : ISA;
+ BA <= IBA;
+ CS_N <= ICS_N;
+ CKE <= ICKE;
+ RAS_N <= (ST==SC_CL+mLENGTH) ? 1'b0 : IRAS_N;
+ CAS_N <= (ST==SC_CL+mLENGTH) ? 1'b1 : ICAS_N;
+ WE_N <= (ST==SC_CL+mLENGTH) ? 1'b0 : IWE_N;
+ PM_STOP <= (ST==SC_CL+mLENGTH) ? 1'b1 : 1'b0;
+ PM_DONE <= (ST==SC_CL+SC_RCD+mLENGTH+2) ? 1'b1 : 1'b0;
+ DQM <= ( active && (ST>=SC_CL) ) ? ( ((ST==SC_CL+mLENGTH) && Write)? 2'b11 : 2'b00 ) : 2'b11 ;
+ mDATAOUT<= DQ;
+end
+
+assign DQ = oe ? DQOUT : `DSIZE'hzzzz;
+assign active = Read | Write;
+
+always@(posedge CLK or negedge RESET_N)
+begin
+ if(RESET_N==0)
+ begin
+ CMD <= 0;
+ ST <= 0;
+ Pre_RD <= 0;
+ Pre_WR <= 0;
+ Read <= 0;
+ Write <= 0;
+ OUT_VALID <= 0;
+ IN_REQ <= 0;
+ mWR_DONE <= 0;
+ mRD_DONE <= 0;
+ end
+ else
+ begin
+ Pre_RD <= mRD;
+ Pre_WR <= mWR;
+ case(ST)
+ 0: begin
+ if({Pre_RD,mRD}==2'b01)
+ begin
+ Read <= 1;
+ Write <= 0;
+ CMD <= 2'b01;
+ ST <= 1;
+ end
+ else if({Pre_WR,mWR}==2'b01)
+ begin
+ Read <= 0;
+ Write <= 1;
+ CMD <= 2'b10;
+ ST <= 1;
+ end
+ end
+ 1: begin
+ if(CMDACK==1)
+ begin
+ CMD<=2'b00;
+ ST<=2;
+ end
+ end
+ default:
+ begin
+ if(ST!=SC_CL+SC_RCD+mLENGTH+1)
+ ST<=ST+1;
+ else
+ ST<=0;
+ end
+ endcase
+
+ if(Read)
+ begin
+ if(ST==SC_CL+SC_RCD+1)
+ OUT_VALID <= 1;
+ else if(ST==SC_CL+SC_RCD+mLENGTH+1)
+ begin
+ OUT_VALID <= 0;
+ Read <= 0;
+ mRD_DONE <= 1;
+ end
+ end
+ else
+ mRD_DONE <= 0;
+
+ if(Write)
+ begin
+ if(ST==SC_CL-1)
+ IN_REQ <= 1;
+ else if(ST==SC_CL+mLENGTH-1)
+ IN_REQ <= 0;
+ else if(ST==SC_CL+SC_RCD+mLENGTH)
+ begin
+ Write <= 0;
+ mWR_DONE<= 1;
+ end
+ end
+ else
+ mWR_DONE<= 0;
+
+ end
+end
+// Internal Address & Length Control
+always@(posedge CLK or negedge RESET_N)
+begin
+ if(!RESET_N)
+ begin
+ rWR1_ADDR <= 0;
+ rWR2_ADDR <= 22'h100000;
+ rRD1_ADDR <= 0;
+ rRD2_ADDR <= 22'h100000;
+ rWR1_MAX_ADDR <= 640*480;
+ rWR2_MAX_ADDR <= 22'h100000+640*480;
+ rRD1_MAX_ADDR <= 640*480;
+ rRD2_MAX_ADDR <= 22'h100000+640*480;
+ rWR1_LENGTH <= 256;
+ rWR2_LENGTH <= 256;
+ rRD1_LENGTH <= 256;
+ rRD2_LENGTH <= 256;
+ end
+ else
+ begin
+ // Write Side 1
+ if(WR1_LOAD)
+ begin
+ rWR1_ADDR <= WR1_ADDR;
+ rWR1_LENGTH <= WR1_LENGTH;
+ end
+ else if(mWR_DONE&WR_MASK[0])
+ begin
+ if(rWR1_ADDR<rWR1_MAX_ADDR-rWR1_LENGTH)
+ rWR1_ADDR <= rWR1_ADDR+rWR1_LENGTH;
+ else
+ rWR1_ADDR <= WR1_ADDR;
+ end
+ // Write Side 2
+ if(WR2_LOAD)
+ begin
+ rWR2_ADDR <= WR2_ADDR;
+ rWR2_LENGTH <= WR2_LENGTH;
+ end
+ else if(mWR_DONE&WR_MASK[1])
+ begin
+ if(rWR2_ADDR<rWR2_MAX_ADDR-rWR2_LENGTH)
+ rWR2_ADDR <= rWR2_ADDR+rWR2_LENGTH;
+ else
+ rWR2_ADDR <= WR2_ADDR;
+ end
+ // Read Side 1
+ if(RD1_LOAD)
+ begin
+ rRD1_ADDR <= RD1_ADDR;
+ rRD1_LENGTH <= RD1_LENGTH;
+ end
+ else if(mRD_DONE&RD_MASK[0])
+ begin
+ if(rRD1_ADDR<rRD1_MAX_ADDR-rRD1_LENGTH)
+ rRD1_ADDR <= rRD1_ADDR+rRD1_LENGTH;
+ else
+ rRD1_ADDR <= RD1_ADDR;
+ end
+ // Read Side 2
+ if(RD2_LOAD)
+ begin
+ rRD2_ADDR <= RD2_ADDR;
+ rRD2_LENGTH <= RD2_LENGTH;
+ end
+ else if(mRD_DONE&RD_MASK[1])
+ begin
+ if(rRD2_ADDR<rRD2_MAX_ADDR-rRD2_LENGTH)
+ rRD2_ADDR <= rRD2_ADDR+rRD2_LENGTH;
+ else
+ rRD2_ADDR <= RD2_ADDR;
+ end
+ end
+end
+// Auto Read/Write Control
+always@(posedge CLK or negedge RESET_N)
+begin
+ if(!RESET_N)
+ begin
+ mWR <= 0;
+ mRD <= 0;
+ mADDR <= 0;
+ mLENGTH <= 0;
+ end
+ else
+ begin
+ if( (mWR==0) && (mRD==0) && (ST==0) &&
+ (WR_MASK==0) && (RD_MASK==0) &&
+ (WR1_LOAD==0) && (RD1_LOAD==0) &&
+ (WR2_LOAD==0) && (RD2_LOAD==0) )
+ begin
+ // Write Side 1
+ if( (write_side_fifo_rusedw1 >= rWR1_LENGTH) && (rWR1_LENGTH!=0) )
+ begin
+ mADDR <= rWR1_ADDR;
+ mLENGTH <= rWR1_LENGTH;
+ WR_MASK <= 2'b01;
+ RD_MASK <= 2'b00;
+ mWR <= 1;
+ mRD <= 0;
+ end
+ // Write Side 2
+ else if( (write_side_fifo_rusedw2 >= rWR2_LENGTH) && (rWR2_LENGTH!=0) )
+ begin
+ mADDR <= rWR2_ADDR;
+ mLENGTH <= rWR2_LENGTH;
+ WR_MASK <= 2'b10;
+ RD_MASK <= 2'b00;
+ mWR <= 1;
+ mRD <= 0;
+ end
+ // Read Side 1
+ else if( (read_side_fifo_wusedw1 < rRD1_LENGTH) )
+ begin
+ mADDR <= rRD1_ADDR;
+ mLENGTH <= rRD1_LENGTH;
+ WR_MASK <= 2'b00;
+ RD_MASK <= 2'b01;
+ mWR <= 0;
+ mRD <= 1;
+ end
+ // Read Side 2
+ else if( (read_side_fifo_wusedw2 < rRD2_LENGTH) )
+ begin
+ mADDR <= rRD2_ADDR;
+ mLENGTH <= rRD2_LENGTH;
+ WR_MASK <= 2'b00;
+ RD_MASK <= 2'b10;
+ mWR <= 0;
+ mRD <= 1;
+ end
+ end
+ if(mWR_DONE)
+ begin
+ WR_MASK <= 0;
+ mWR <= 0;
+ end
+ if(mRD_DONE)
+ begin
+ RD_MASK <= 0;
+ mRD <= 0;
+ end
+ end
+end
+
+endmodule