sdram控制器设计

sdram控制器设计SDRAM控制器

大家好,又见面了,我是你们的朋友全栈君。

同步动态随机存取内存(synchronous dynamic random-access memory,简称SDRAM)是有一个同步接口的动态随机存取内存(DRAM)。SDRAM的特点是需要定期进行刷新操作,这也要求SDRAM需要一个控制器来对SDRAM进行控制,更为详细的SDRAM的知识可以上网进行查找,这里不再做过多的阐述。

SDRAM在上电之后要进行初始化操作,初始化操作包括无操作稳定延时一段时间(常见为延时200us),然后所有bank都要预充电,之后进行两次刷新操作,最后对寄存器赋值(控制操作模式、CAS潜伏期、burst突发长度,突发传输方式等)。

初始化结束之后,SDRAM就可以进行正常的读写操作,不过需要注意,SDRAM要定时刷新,因为SDRAM是使用电容存储数据,但是电容会漏电(无法避免),因此需要刷新。

下面给出我设计的SDRAM控制器的有限状态机图(画的比较仓促,可能会出现漏洞,欢迎询问)

<span role="heading" aria-level="2">sdram控制器设计

 

 

 

 

 

 接下来我给出设计的verilog程序的结构图

<span role="heading" aria-level="2">sdram控制器设计

 

 

 

结构图顶层信号在程序中可以见到;为了可以更好的测试SDRAM控制器,所以特地编写了一个master,用于接受或发送数据。

master的顶层信号为:

input clk,
input rst_n,
input idle_sdram,//高位表示sdram正处在空闲状态,可以接收发数据
input req_send,//用于测试,提醒master开始发送数据
input addr_ready,//告诉master更新地址
input flag_dq_wr,//在写操作时,告诉master何时更新数据
input [15:0] dq_rd,//读操作接收读到的地址
output reg con_tran,//用于连续发送,当master处于连续发送时,就一直保持高位,当地址已经完全发送出去时,等到master更新地址时,拉低该位,表示数据传输完成(完成传输数据时,master地址需要跳到默认地址去)
output reg [24:0] addr_out,//给控制器输出的地址,最高位表示读或者写,2位bank地址位,13位行地址位,9位列地址位
output reg req_wr_rd,//向控制器发出的读写请求
output reg [15:0] dq_wr//写数据

 

SDRAM控制器的顶层信号为:

input clk,
input rst_n,
input con_tran,//为高表示master连续发送,默认为低位。
input [24:0] addr_in,//最高位表示读或者写,高表示为写,低位表示为读,然后依次为bank地址,行地址,列地址
input req_wr_rd,//master第一次传输数据时,将其拉高,与地址同时发出,有效位为单个周期
input [15:0] dq_wr,

output wire [1:0] sdram_dqm,
output wire sdram_clk,
output wire sdram_cke,
output wire sdram_cs_n,
output wire sdram_ras_n,
output wire sdram_cas_n,
output wire sdram_we_n,
output reg [12:0] sdram_addr,
output reg [1:0] sdram_bank_addr,
inout wire [15:0] sdram_dq_in,

output wire [15:0] dq_rd,
output wire addr_ready, //为高时,告诉master更新行列地址
output wire flag_dq_wr,
//output wire idle_sdram,//告诉master sdram是否处于空闲状态
output reg req_send//插入的测试点,提示master开始发送信号

 

SDRAM控制器中读写模块比较复杂,其他模块很简单。该控制器设置burst长度为4,进入读写状态最开始进行行激活,之后若读写地址都在该行,那么可以连续的读写,不需要再行激活,并且连续读写之间没有空闲周期;若前后行地址不一致,则在预充电后,由读写状态直接进入IDLE状态,然后再次进入读写状态;每次进入和离开读写状态只进行一次行激活和预充电;可以保证由读转到写时,完全读出数据之后才进行写操作,同样中间不会有多有空闲周期。

下面给出一种情况下,读写模块里面部分信号的时序图

<span role="heading" aria-level="2">sdram控制器设计

 

 

 

给出Modelsim仿真的一部分情况

开始

<span role="heading" aria-level="2">sdram控制器设计

 

 

 连续读写时遇到刷新

<span role="heading" aria-level="2">sdram控制器设计

 

 

 换行

<span role="heading" aria-level="2">sdram控制器设计

 

 

 

最后给出代码

读写模块

 1 module sdram_rd_wr(  2 input clk,  3 input rst_n,  4 input aref_req,  5 input wr_rd_en,  6 input con_tran,  7 input [24:0] addr_in,  8 output reg [3:0] cmd_reg,  9 output reg [12:0] sdram_addr,  10 output reg [1:0] sdram_bank_addr,  11 output reg flag_dq_wr,  12 output wire addr_ready,  13 output reg end_wr_rd,  14 output reg flag_aref_req  15 );  16  17 //1+2+13+9  18  19 reg [24:0] addr_in_reg;  20  21  22  23  24 reg row_act;  25  26 localparam ROWACT =4'b0011;  27 localparam NOP =4'b0111;  28 localparam WR =4'b0100;  29 localparam RD =4'b0101;  30 localparam PRE =4'b0010;  31  32 wire flag_wr_rd;  33 reg flag_wr_rd_a;  34 reg flag_rd2wr;  35  36 reg [1:0] cnt_cmd;  37  38  39  40 reg end_en;  41  42 reg pre_en;  43  44 assign addr_ready=((cnt_cmd==2'd1)&&(con_tran==1'b1))? 1'b1:1'b0;  45 always@(posedge clk, negedge rst_n)  46 if(!rst_n)  47 addr_in_reg<=25'd0;  48 else if(wr_rd_en==1'b1||((end_en==1'b0)&&(cnt_cmd==2'd3)))  49 addr_in_reg<=addr_in;  50 else  51 addr_in_reg<=addr_in_reg;  52  53 always@(posedge clk, negedge rst_n)  54 if(!rst_n)  55 flag_dq_wr<=1'b0;  56 else if((flag_wr_rd==1'b1)&&(cnt_cmd==2'd0)&&(addr_in_reg[24]==1'b1))  57 flag_dq_wr<=1'b1;  58 else if((flag_wr_rd==1'b1)&&(cnt_cmd==2'd0)&&(addr_in_reg[24]==1'b0))  59 flag_dq_wr<=1'b0;  60 else if(pre_en==1'b1)  61 flag_dq_wr<=1'b0;  62 else  63 flag_dq_wr<=flag_dq_wr;  64  65  66 always@(posedge clk, negedge rst_n)  67 if(!rst_n)  68 row_act<=1'b0;  69 else  70 row_act<=wr_rd_en;  71  72 always@(posedge clk, negedge rst_n)  73 if(!rst_n)  74 cmd_reg<=NOP;  75 else if(row_act)  76 cmd_reg<=ROWACT;  77 else if(flag_wr_rd==1'b1&&cnt_cmd==2'd0) begin  78 if(addr_in_reg[24]==1'b1)  79 cmd_reg<=WR;  80 else  81 cmd_reg<=RD;  82 end  83 else if(pre_en)  84 cmd_reg<=PRE;  85 else  86 cmd_reg<=NOP;  87  88  89 always@(*) begin  90 case(cmd_reg)  91 ROWACT: begin  92 sdram_addr <=addr_in_reg[21:9];  93 sdram_bank_addr <=addr_in_reg[22:21];  94 end  95  96 WR: begin  97 sdram_addr <={3'b000,addr_in_reg[8:0]};  98 sdram_bank_addr <=addr_in_reg[23:22];  99 end 100 RD: begin 101 sdram_addr <={3'b000,addr_in_reg[8:0]}; 102 sdram_bank_addr <=addr_in_reg[23:22]; 103 end 104 PRE: begin 105 sdram_addr <=13'b0_0100_0000_0000;  106 sdram_bank_addr <=2'd0; 107 end 108 NOP: begin 109 sdram_addr <=13'd0; 110 sdram_bank_addr <=2'd0; 111 end 112 default: begin 113 sdram_addr <=13'd0; 114 sdram_bank_addr <=2'd0; 115 end 116 endcase 117 end 118 119 120 always@(posedge clk, negedge rst_n) 121 if(!rst_n) 122 flag_aref_req<=1'b0; 123 else if(aref_req) 124 flag_aref_req<=1'b1; 125 else if(wr_rd_en) 126 flag_aref_req<=1'b0; 127 else 128 flag_aref_req<=flag_aref_req; 129 130 always@(posedge clk, negedge rst_n) 131 if(!rst_n) 132 flag_wr_rd_a<=1'b0; 133 else if(cmd_reg==ROWACT) 134 flag_wr_rd_a<=1'b1;  135 else if(end_en==1'b1) 136 flag_wr_rd_a<=1'b0; 137 else 138 flag_wr_rd_a<=flag_wr_rd_a; 139 140 always@(posedge clk, negedge rst_n) 141 if(!rst_n) 142 flag_rd2wr<=1'b1; 143 else if(cnt_cmd==2'd3&&addr_in[24]==1'b0&&addr_in_reg[24]==1'b1&&!end_en) 144 flag_rd2wr<=1'b0; 145 else 146 flag_rd2wr<=1'b1; 147 148 assign flag_wr_rd=flag_rd2wr&flag_wr_rd_a; 149 150 always@(posedge clk, negedge rst_n) 151 if(!rst_n) 152 cnt_cmd<=2'd0; 153 else if(flag_wr_rd==1'b1) begin  154 if(cnt_cmd==2'd3) 155 cnt_cmd<=2'd0; 156 else 157 cnt_cmd<=cnt_cmd+1'b1; 158 end 159 else 160 cnt_cmd<=2'd0; 161 162 always@(posedge clk, negedge rst_n) 163 if(!rst_n) 164 end_en<=1'b0; 165 else if(cnt_cmd==2'd2) begin  166 if(con_tran==1'b0) 167 end_en<=1'b1; 168 else if(con_tran==1'b1&&flag_aref_req==1'b1) 169 end_en<=1'b1; 170 else if((con_tran==1'b1)&& !(addr_in[21:9]==addr_in_reg[21:9]))  171 end_en<=1'b1; 172 else 173 end_en<=1'b0; 174 end 175 else 176 end_en<=1'b0; 177 178 always@(posedge clk, negedge rst_n) 179 if(!rst_n) 180 pre_en<=1'b0; 181 else if(end_en) 182 pre_en<=1'b1; 183 else 184 pre_en<=1'b0; 185 186 187 always@(posedge clk,negedge rst_n) 188 if(!rst_n) 189 end_wr_rd<=1'b0; 190 else if(pre_en) 191 end_wr_rd<=1'b1; 192 else 193 end_wr_rd<=1'b0; 194 195 endmodule 

初始化模块

 1 module sdram_init(  2 input clk,  3 input rst_n,  4 output wire [12:0] init_addr,  5 output wire [1:0] bank_addr,  6 output reg [3:0] cmd_reg,  7 output reg end_init,  8 output reg flag_init  9 );  10  11  12 reg flag_delay;  13  14  15 reg [13:0] cnt_delay;  16 localparam DELAY=14'd10000;   17  18  19 reg end_delay;  20  21  22 reg [3:0] cnt_init;  23  24  25 localparam INIT_NOP =4'b0111;  26 localparam INIT_PRE =4'b0010;  27 localparam INIT_ARF =4'b0001;  28 localparam INIT_MODSET=4'b0000;  29  30  31 always@(posedge clk, negedge rst_n)  32 if(!rst_n)  33 flag_delay<=1'b1;  34 else if(cnt_delay==DELAY)  35 flag_delay<=1'b0;  36 else  37 flag_delay<=flag_delay;  38  39  40  41  42 always@(posedge clk, negedge rst_n)  43 if(!rst_n)  44 cnt_delay<=14'd0;  45 else if(flag_delay==1'b1)  46 cnt_delay<=cnt_delay+1'b1;  47 else  48 cnt_delay<=14'd0;   49  50  51  52 always@(posedge clk, negedge rst_n)  53 if(!rst_n)  54 end_delay<=1'b1;  55 else if(cnt_delay==DELAY)  56 end_delay<=1'b1;  57 else  58 end_delay<=1'b0;  59  60  61 always@(posedge clk,negedge rst_n)  62 if(!rst_n)  63 cnt_init<=4'd0;  64 else if( flag_delay==1'b0 && flag_init==1'b1)  65 cnt_init<=cnt_init+1'b1;  66 else if(cnt_init==4'd12)  67 cnt_init<=4'd0;  68 else  69 cnt_init<=cnt_init;  70  71  72  73 always@(posedge clk, negedge rst_n)  74 if(!rst_n)  75 flag_init<=1'b1;  76 else if(end_init==1'b1)  77 flag_init<=1'b0;  78 else  79 flag_init<=flag_init;  80  81  82 always@(posedge clk, negedge rst_n)  83 if(!rst_n)  84 end_init<=1'b0;  85 else if(cnt_init==4'd12)  86 end_init<=1'b1;  87 else  88 end_init<=1'b0;  89  90  91  92  93  94  95  96  97 always@(posedge clk, negedge rst_n)  98 if(!rst_n)  99 cmd_reg<=INIT_NOP; 100 else if((flag_delay==1'b0) && (flag_init==1'b1)) 101 case(cnt_init) 102 4'd1: cmd_reg<=INIT_PRE; 103 4'd3: cmd_reg<=INIT_ARF; 104 4'd7: cmd_reg<=INIT_ARF; 105 4'd11:cmd_reg<=INIT_MODSET; 106 default: cmd_reg<=INIT_NOP; 107 endcase 108 else 109 cmd_reg<=INIT_NOP; 110 111 112 113 114 115 assign {bank_addr[1:0],init_addr[12:0]}=(cmd_reg==INIT_MODSET)? 15'b000_0000_0011_0010:15'b000_0100_0000_0000; 116 117 118 119 endmodule 

刷新计数器

module aref_cunter( input clk, input rst_n, input end_init, output wire aref_req ); reg [8:0] aref_cnt; reg flag_aref; localparam AREF_DELAY=9'd380; always@(posedge clk, negedge rst_n) if(!rst_n) flag_aref<=1'b0; else if(end_init==1'b1) flag_aref<=1'b1; else flag_aref<=flag_aref; always@(posedge clk, negedge rst_n) if(!rst_n) aref_cnt<=9'd0; else if (flag_aref==1'b1) begin  if(aref_cnt==AREF_DELAY) aref_cnt<=9'd0; else aref_cnt<=aref_cnt+1'b1; end else aref_cnt<=9'd0; assign aref_req=(aref_cnt==AREF_DELAY) ? 1'b1:1'b0; endmodule

刷新模块

module sdram_aref( input clk, input rst_n, input aref_en, output reg [3:0] cmd_reg, output reg end_aref ); reg [3:0] aref_cnt; reg flag_aref; localparam AREF=4'b0001; localparam NOP =4'b0111; always@(posedge clk, negedge rst_n) if(!rst_n) flag_aref<=1'b0; else if(aref_en==1'b1) flag_aref<=1'b1; else if(aref_cnt==4'd12) flag_aref<=1'b0; else flag_aref<=flag_aref; always@(posedge clk, negedge rst_n) if(!rst_n) aref_cnt<=4'd0; else if(aref_cnt==4'd12) aref_cnt<=4'd0; else if(flag_aref==1'b1) aref_cnt<=aref_cnt+1'b1; else aref_cnt<=4'd0; always@(*) begin case(aref_cnt) 4'd1: cmd_reg<=AREF; 4'd5: cmd_reg<=AREF; default: cmd_reg<=NOP; endcase end always@(posedge clk, negedge rst_n) if (!rst_n) end_aref<=1'b0; else if(aref_cnt==4'd12) end_aref<=1'b1; else end_aref<=1'b0; endmodule 

SDRAM控制器顶层模块

 1 module sdram_control_top(  2 input clk,  3 input rst_n,  4 input con_tran,  5 input [24:0] addr_in,  6 input req_wr_rd,  7 input [15:0] dq_wr,  8 output wire [1:0] sdram_dqm,  9 output wire sdram_clk,  10 output wire sdram_cke,  11 output wire sdram_cs_n,  12 output wire sdram_ras_n,  13 output wire sdram_cas_n,  14 output wire sdram_we_n,  15 output wire [15:0] dq_rd,  16 output reg [12:0] sdram_addr,  17 output reg [1:0] sdram_bank_addr,  18 inout wire [15:0] sdram_dq_in,  19 output wire addr_ready,  20 output wire flag_dq_wr,  21 output wire idle_sdram,  22 output reg req_send  23 );  24  25  26 wire aref_req;  27 reg wr_rd_en;  28 wire [3:0] cmd_wr_rd;  29 wire [12:0] addr_wr_rd;  30 wire [1:0] bank_addr_wr_rd;  31 wire end_wr_rd;  32 wire flag_aref_req;  33 wire aref_req_wr_rd;  34  35 wire [12:0] addr_init;  36 wire [1:0] bank_addr_init;  37 wire [3:0] cmd_init;  38 wire end_init;  39 wire flag_init;  40  41  42 reg aref_en;  43 wire [3:0] cmd_aref;  44 wire end_aref;  45  46 reg [3:0] state;  47 reg [3:0] sd_cmd;  48  49 localparam NOP=4'b0111;  50  51 sdram_rd_wr U1(  52  .clk (clk),  53  .rst_n (rst_n),  54  .aref_req (aref_req_wr_rd),  55  .wr_rd_en (wr_rd_en),  56  .con_tran (con_tran),  57  .addr_in (addr_in),  58  .cmd_reg (cmd_wr_rd),  59  .sdram_addr (addr_wr_rd),  60  .sdram_bank_addr(bank_addr_wr_rd),  61  .flag_dq_wr (flag_dq_wr),  62  .addr_ready (addr_ready),  63  .end_wr_rd (end_wr_rd),  64  .flag_aref_req (flag_aref_req)  65 );  66  67 sdram_init U2(  68  .clk (clk),  69  .rst_n (rst_n),  70  .init_addr (addr_init),  71  .bank_addr (bank_addr_init),  72  .cmd_reg (cmd_init),  73  .end_init (end_init),  74  .flag_init (flag_init)  75 );  76  77 aref_cunter U3(  78  .clk (clk),  79  .rst_n (rst_n),  80  .end_init (end_init),  81  .aref_req (aref_req)  82 );  83  84 sdram_aref U4(  85  .clk (clk),  86  .rst_n (rst_n),  87  .aref_en (aref_en),  88  .cmd_reg (cmd_aref),  89  .end_aref (end_aref)  90 );  91  92 localparam ST_IDLE =4'b0001,  93 ST_AREF =4'b0010,  94 ST_WR_RD=4'b0100,  95 ST_INIT =4'b1000;  96  97 always@(posedge clk,negedge rst_n)  98 if(!rst_n)  99 state<=ST_INIT; 100 else case(state) 101 ST_INIT: if(end_init==1'b1) 102 state<=ST_IDLE; 103 else 104 state<=ST_INIT; 105 ST_IDLE: if(aref_req==1'b1) 106 state<=ST_AREF; 107 else if(req_wr_rd==1'b1||con_tran==1'b1) 108 state<=ST_WR_RD; 109 else 110 state<=ST_IDLE; 111 ST_AREF: if(end_aref==1'b1) 112 state<=ST_IDLE; 113 else 114 state<=ST_AREF; 115 ST_WR_RD: if(end_wr_rd==1'b1&&flag_aref_req==1'b1) 116 state<=ST_AREF; 117 else if(end_wr_rd==1'b1&&flag_aref_req==1'b0) 118 state<=ST_IDLE; 119 else 120 state<=ST_WR_RD; 121 default: state<=ST_INIT; 122 endcase 123 124 always@(*) begin 125 case(state) 126 ST_INIT: begin 127 sd_cmd <=cmd_init; 128 sdram_addr <=addr_init; 129 sdram_bank_addr<=bank_addr_init; 130 end 131 ST_IDLE: begin 132 sd_cmd <=NOP; 133 sdram_addr <=13'd0; 134 sdram_bank_addr<=2'd0; 135 end 136 ST_AREF: begin 137 sd_cmd <=cmd_aref; 138 sdram_addr <=13'd0; 139 sdram_bank_addr<=2'd0; 140 end 141 ST_WR_RD: begin 142 sd_cmd <=cmd_wr_rd; 143 sdram_addr <=addr_wr_rd; 144 sdram_bank_addr<=bank_addr_wr_rd; 145 end 146 default: begin 147 sd_cmd <=NOP; 148 sdram_addr <=13'd0; 149 sdram_bank_addr<=2'd0; 150 end 151 endcase 152 end 153 154 always@(posedge clk, negedge rst_n) 155 if(!rst_n) 156 wr_rd_en<=1'b0; 157 else if(state==ST_IDLE&&req_wr_rd==1'b1||state==ST_IDLE&&con_tran==1'b1) 158 wr_rd_en<=1'b1; 159 else 160 wr_rd_en<=1'b0; 161 162 always@(posedge clk, negedge rst_n) 163 if(!rst_n) 164 aref_en<=1'b0; 165 else if(state==ST_IDLE&&aref_req) 166 aref_en<=1'b1; 167 else if(end_wr_rd==1'b1&&flag_aref_req==1'b1) 168 aref_en<=1'b1; 169 else 170 aref_en<=1'b0; 171 172 assign aref_req_wr_rd=(aref_req==1'b1&&state==ST_WR_RD)?1'b1:1'b0; 173 assign idle_sdram=(state==ST_IDLE)?1'b1:1'b0; 174 175 assign {sdram_cs_n,sdram_ras_n,sdram_cas_n,sdram_we_n}=sd_cmd; 176 assign sdram_cke=1'b1; 177 assign sdram_clk=~clk; 178 assign sdram_dqm=2'b00; 179 assign sdram_dq_in=(flag_dq_wr==1'b1)?dq_wr:{16{1'bz}}; 180 assign dq_rd=sdram_dq_in; 181 182 183 always@(posedge clk, negedge rst_n) 184 if(!rst_n) 185 req_send<=1'b0; 186 else if(end_init==1'b1) 187 req_send<=1'b1; 188 else 189 req_send<=1'b0; 190 191 endmodule 

 

上述代码可以组成一个完整的SDRAM控制器,上述代码不允许使用在商业或者论文中,本人保留一切权利。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/154672.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 长尾分布(long-tail distribution)和长尾效应「建议收藏」

    长尾分布(long-tail distribution)和长尾效应「建议收藏」长尾分布(long-taildistribution)和长尾效应1、长尾效应作者:赵澈链接:https://www.zhihu.com/question/20027490/answer/20420381来源:知乎长尾效应其实是幂率分布的通俗提法,在物理上也被称为无标度现象,这种现象在自然界与社会生活中都相当地常见,可参考幂律分布_互动百科。里面也提到之所以叫无标度,是因为「系统中个体的尺度相差悬殊,缺乏一个优选的规模」。如下图这般,极少数个体(横轴)对应极高的值(纵轴),而拥有极低值的个体,数

    2022年10月27日
  • Django(50)drf异常模块源码分析

    Django(50)drf异常模块源码分析异常模块源码入口APIView类中dispatch方法中的:response=self.handle_exception(exc)源码分析我们点击handle_exception跳转,查看该

  • QueryInterface 实现及使用的完整的例子

    QueryInterface 实现及使用的完整的例子下面我们将把前面所提到过和各代码段组合起来,以构成一个说明QueryInterface实现及使用的完整例子。总的来说可以将这些代码分成三部分。第一部分是接口IX、IY和IZ的定义部分。接口IUnknown的定义在Win32SDK的头文件1见UNKNWN.H中。第二部分是组件的实现。类CA实现了一个支持IX和IY接口的组件。QueryInterface的实现

  • 最详细的maven配置——报错了你打我[通俗易懂]

    最详细的maven配置——报错了你打我[通俗易懂]目录1、前言2、下载3、配置PATH、settings.xml以及本地仓库3.1、配置path3.2、配置settings.xml和本地仓库4、在IDEA中配置Maven1、前言maven说的简短一点就是一个大型的jar包管理工具,类似于工具人。只要有了maven,就不用去幸幸苦苦的找jar包了。wc,爽哉。好了,还是不多bb,我么还是直接干正事。(切记切记:安装maven必须装好jdk)2、下载首先我们还是去官网。瞅瞅最新版的是哪个版本。点我直达当然,玩Windows的人都知道,我们下

  • php 7.2 if else endif 模板语法错误提示的处理

    php 7.2 if else endif 模板语法错误提示的处理

  • 西尔斯罗巴克公司案例分析_巴宝莉滑铁卢

    西尔斯罗巴克公司案例分析_巴宝莉滑铁卢这几天看到网上对WannaCry勒索病毒讨论得沸沸扬扬,不免有些感触。其实该病毒的这次爆发,完全可以类比N年前“熊猫烧香”爆发的情况。也就是国内杀软纷纷歇菜,让本来就没什么技术含量的病毒横行于世。所不同的是,这次在病毒横行的时候,假设有技术爱好者出来质疑国内杀软的查杀水平,那么该杀软厂商的公关人员就会第…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号