`timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2021/08/03 09:39:06 // Design Name: // Module Name: work_4 // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // module work_4(clk,rst_n,wr_req,waddr,wdata,wr_ack,rd_req,rd_ack,rdata,rdata_vld,cke,cs,ras,cas,we,dqm,addr,bank,dq); input clk; input rst_n; input wr_req; input [21:0] waddr;// without [21:0], bank<=waddr[21:20] error input [15:0] wdata; output wr_ack; input rd_req; output rd_ack; output rdata; output rdata_vld; input cke; output cs; output ras; output cas; output we; output dqm; output addr; output bank; output dq; parameter T=10; parameter T_NOP=10000; parameter TRP=2; parameter TRC=6; parameter TMRD=2; parameter TRCD=2; parameter Tread=256; parameter Twrite=256; parameter Tidle=2; parameter MODE_VALUE = 12'b0000_0010_0111;//M9 = 0 burst模式 M6 M5 M4 = 3'b010 输出延时为2个时钟周期;M3 = 0 burst类型(连续模式) M2 M1 M0 = 3'b111 全页模式 // parameter NOP = 1;// parameter CHARGE = 2;// parameter REF = 3;// parameter MODE = 4;// parameter IDLE = 5;// parameter ACTIVE = 6; parameter WRITE = 7; parameter READ = 8; parameter REF2 = 9; reg cs; reg ras; reg cas; reg we; reg wr_ack; reg rd_ack; reg [1:0] dqm; reg [11:0] addr; reg [1:0] bank; reg [15:0] dq; reg [3:0] state_c;//10 reg [3:0] state_n; reg [13:0] count; reg [13:0] x;//2^14=2048*8>10000 reg [10:0] count1;//2^11=2048 reg [3:0] command; reg rdata_vld; wire NOP2CHARGE; wire CHARGE2REF; wire REF2REF2; wire REF22MODE; wire MODE2IDLE ; wire IDLE2REF; wire REF2IDLE; wire IDLE2ACTIVE; wire ACTIVE2WRITE; wire WRITE2CHARGE ; wire CHARGE2IDLE ; wire ACTIVE2READ; wire READ2CHARGE; wire resh_req; reg init_flag; wire wr_flag; wire rd_flag; //reg init_resh_cnt;//初始化过程自动刷新计数 区分REF2REF 还是REF2MODE assign wr_flag= (wr_req==1) && (rd_req==0); assign rd_flag= (rd_req==1); assign resh_req= (wr_req==1 || rd_req==1); assign NOP2CHARGE = (state_c == NOP) && (count==1) ; assign CHARGE2REF= (state_c == CHARGE) && (count==1) && init_flag==1; assign REF2REF2 = (state_c == REF) && (count==1) && (init_flag==1) ; assign REF22MODE = (state_c == REF2) && (count==1) && (init_flag==1) ; assign MODE2IDLE = (state_c == MODE) && (count==1); assign IDLE2REF = (state_c == IDLE) && (count1==1) ;// assign REF2IDLE = (state_c == REF) && (count==1) && (init_flag==0) ;// assign IDLE2ACTIVE = (state_c == IDLE) && (count==1) && ( (wr_flag==1)||(rd_flag==1) ) ; assign ACTIVE2WRITE = (state_c == ACTIVE) && (count==1)&& (wr_flag==1); assign WRITE2CHARGE = (state_c == WRITE) && (count==1); assign CHARGE2IDLE = (state_c == CHARGE) && (count==1) && ( (wr_flag==1)||(rd_flag==1) ); assign ACTIVE2READ = (state_c == ACTIVE) && (count==1)&& (rd_flag==1) ; assign READ2CHARGE = (state_c == READ) && (count==1); always @(posedge clk or negedge rst_n) begin if (rst_n==1'b0) begin init_flag <= 1; end else if (MODE2IDLE) begin init_flag <= 0; end end //always @(posedge clk or negedge rst_n) begin // if (rst_n==1'b0) begin // init_resh_cnt <= 0; // end // else if (REF2REF) begin // init_resh_cnt <= 1; // end // else if (REF2MODE) begin // init_resh_cnt <= 0; // end //end always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin state_c<=NOP; end else begin state_c<=state_n; end end always @ (*) begin if (!rst_n) begin state_n=state_c; end else begin case (state_c) NOP : begin//1 if (NOP2CHARGE) begin state_n=CHARGE; end else begin state_n=state_c; end end CHARGE : begin//2 if (CHARGE2REF) begin state_n=REF; end else if (CHARGE2IDLE) begin state_n=IDLE; end else begin state_n=state_c; end end REF : begin//3 if (REF2IDLE) begin state_n=IDLE; end else if (REF2REF2) begin state_n=REF2; end else begin state_n=state_c; end end REF2 : begin//3 if (REF22MODE) begin state_n=MODE; end else begin state_n=state_c; end end MODE : begin// if (MODE2IDLE) begin state_n=IDLE; end else begin state_n=state_c; end end IDLE : begin// if (IDLE2REF) begin state_n=REF; end else if (IDLE2ACTIVE) begin state_n=ACTIVE; end else begin state_n=state_c; end end ACTIVE : begin// if (ACTIVE2WRITE) begin state_n=WRITE; end else if (ACTIVE2READ) begin state_n=READ; end else begin state_n=state_c; end end WRITE : begin if (WRITE2CHARGE) begin state_n=CHARGE; end else begin state_n=state_c; end end READ : begin if (READ2CHARGE) begin state_n=CHARGE; end else begin state_n=state_c; end end default : begin//default state_n=NOP; end endcase end end // always @(*)begin if(state_c==CHARGE) begin x = TRP; end else if(state_c==REF || state_c==REF2 )begin x = TRC; end else if(state_c==MODE)begin x = TMRD; end else if(state_c==ACTIVE )begin x = TRCD; end else if(state_c==WRITE )begin x = Twrite; end else if(state_c== READ )begin x = Tread; end else if(state_c== IDLE && (wr_flag==0 || rd_flag==0))begin x = Tidle; end else begin x = T_NOP;//1 end end //count always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin count<= T_NOP-1; end else begin if (count==0) count<= x-1; else count<=count-1; end end always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin count1<=1300-1; end else if (state_c==IDLE && wr_flag==0 && rd_flag==0 ) begin//6 if (count==0) count1<= 1300-1; else count1<=count-1; end else begin count1<= 1300-1; end end //command always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin command<=4'b0111; end else begin if (NOP2CHARGE||WRITE2CHARGE ||READ2CHARGE) command<=4'b0010; else if (CHARGE2REF || IDLE2REF) command<=4'b0001; else if (REF22MODE) command<=4'b0000; else if (IDLE2ACTIVE) command<=4'b0011; else if (ACTIVE2WRITE) command<=4'b0100; else if (ACTIVE2READ) command<=4'b0101; else command<=4'b0111; end end //assign {cs,ras,cas,we}=command; always @(*) begin cs=command[3]; ras=command[2]; cas=command[1]; we=command[0]; end //dqm always @(posedge clk or negedge rst_n) begin if (!rst_n) begin dqm<=2'b00; end else begin if (state_c==NOP||state_c==CHARGE|| state_c==REF ||state_c==MODE) dqm<=2'b11; else dqm<=2'b00; end end //addr always @(*) begin if (!rst_n) begin addr=12'b0000_0000_0000; end else begin if (state_c==MODE) addr=MODE_VALUE; else if (state_c==CHARGE) addr=12'b0100_0000_0000; else if (state_c==WRITE || state_c==READ) addr=waddr[7:0]; else if (state_c==ACTIVE ) addr=waddr[19:8]; else addr=12'b0; end end //bank always @(posedge clk or negedge rst_n) begin if (!rst_n) begin bank<=2'b00; end else begin if (ACTIVE2WRITE || IDLE2ACTIVE || ACTIVE2READ || IDLE2ACTIVE) bank<=waddr[21:20]; else bank<=2'b00; end end //dq always @(*) begin if (!rst_n) begin dq=16'hzzzz; end else if (state_c==WRITE) begin// dq=wdata; end else if (state_c==READ) begin// dq=rdata; end else dq=16'hzzzz; end //wr_ack assign wr_ack=wr_active_start always @(posedge clk or negedge rst_n) begin if (!rst_n) begin wr_ack<=0; end else begin if (ACTIVE2WRITE) //(state_c == WR_ACTIVE) && (count==1) wr_ack<=1; else wr_ack<=0; end end //rd_ack always @(posedge clk or negedge rst_n) begin if (!rst_n) begin rd_ack<=0; end else begin if (ACTIVE2READ) //(state_c == WR_ACTIVE) && (count==1) rd_ack<=1; else rd_ack<=0; end end //rdata_vld always @(*) begin if (!rst_n) begin rdata_vld=0; end else begin if (state_c==READ) //(state_c == WR_ACTIVE) && (count==1) rdata_vld=1; else rdata_vld=0; end end endmodule
`timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2021/08/03 19:53:57 // Design Name: // Module Name: work_4_test // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // module work_4_test(); reg clk; reg rst_n; reg wr_req; reg [21:0] waddr;// without [21:0], bank<=waddr[21:20] error reg [15:0] wdata; wire wr_ack; reg rd_req; wire rd_ack; wire rdata; wire rdata_vld; reg cke; wire cs; wire ras; wire cas; wire we; wire dqm; wire addr; wire bank; wire dq; work_4 work_4_test( .clk(clk), .rst_n(rst_n), .wr_req(wr_req), .waddr(waddr), .wdata(wdata), .wr_ack(wr_ack), .rd_req(rd_req), .rd_ack(rd_ack), .rdata(rdata), .rdata_vld(rdata_vld), .cke(cke), .cs(cs), .ras(ras), .cas(cas), .we(we), .dqm(dqm), .addr(addr), .bank(bank), .dq(dq) ); initial begin clk=1'b0; forever #5 clk=~clk; end initial begin rst_n=1'b0; cke=1'b1; waddr=22'b01_0001_0111_0000_0001_1010; wdata=16'b0111_0000_0001_1010; wr_req=1'b0; rd_req=1'b1; #7 rst_n=1'b1; end endmodule