⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem_interface_top_tap_ctrl_0.txt

📁 基于Xilinx FPGA的DDRSDRAM的Verilog控制代码
💻 TXT
📖 第 1 页 / 共 2 页
字号:
      if (reset_int == 1'b1)
        second_edge_tap_count[5:0]  <= 6'b000000;
      else if ((transition[1:0] == 2'b10) && (second_edge == 1'b0))
        second_edge_tap_count[5:0]  <= tap_counter[5:0];
   end

   always @ (posedge CLK) begin
      if (reset_int == 1'b1)
        pulse_width_tap_count[5:0] <= 6'b000000;
      else if (second_edge_r1 == 1'b1)
        pulse_width_tap_count[5:0] <= (second_edge_tap_count[5:0] -
                                       first_edge_tap_count[5:0]);
   end

   always @ (posedge CLK) begin
      if (reset_int == 1'b1)
        pulse_center_tap_count[5:0] <= 6'b000000;
      else if (second_edge_r2 == 1'b1)
        pulse_center_tap_count[5:0] <= pulse_width_tap_count[5:0] >> 1;
                        // Shift right to divide by 2 and find pulse center
   end

   always @ (posedge CLK) begin
      if (reset_int == 1'b1)
        data_bit_tap_count[5:0]     <= 6'b000000;
      else if (second_edge_r3 == 1'b1)  // 2 edges detected
        data_bit_tap_count[5:0]  <= first_edge_tap_count[5:0] +
                               pulse_center_tap_count[5:0];
      else if ((transition[1:0] == 2'b01) && ((tap_counter[5:0] == 6'b111111)))
                                        // Only 1 edge detected
        if (first_edge_tap_count[5] == 1'b0)
          data_bit_tap_count[5:0]  <= first_edge_tap_count[5:0] + 6'b010000;
        else
          data_bit_tap_count[5:0]  <= first_edge_tap_count[5:0] - 6'b010000;
      else if ((transition[1:0] == 2'b00) && ((tap_counter[5:0] == 6'b111111)))
                                         // No edges detected
        data_bit_tap_count[5:0]  <= 6'b100000;
   end


   // Logic required to determine whether the registered DQS is on the edge of
   //  meeting setup time in the FPGA clock domain. If DQS is on the edge, then
   // the vector 'flag' will not be "1111" or "0000" and edge detection will not
   //  be executed.
   // If DQS is not on the edge, then the vector 'flag' will be "1111" or "0000"
   //  and edge detection will be executed.

   always @ (posedge CLK) begin
      if (reset_int == 1'b1) begin
         flag[3:0] <= 4'b0000;
      end
      else if (detect_edge_idle_r3 == 1'b1 || idelay_inc_idle_r3 == 1'b1 ||
               idelay_rst_idle_r3 == 1'b1) begin
         if (curr_dqs_level != prev_dqs_level)
           flag[0] <= 1'b0;
         else
           flag[0] <= 1'b1;
      end
      else if (detect_edge_idle_r4 == 1'b1 || idelay_inc_idle_r4 == 1'b1 ||
               idelay_rst_idle_r4 == 1'b1) begin
         if (curr_dqs_level != prev_dqs_level)
           flag[1] <= 1'b0;
         else
           flag[1] <= 1'b1;
      end
      else if (detect_edge_idle_r5 == 1'b1 || idelay_inc_idle_r5 == 1'b1  ||
               idelay_rst_idle_r5 == 1'b1) begin
         if (curr_dqs_level != prev_dqs_level)
           flag[2] <= 1'b0;
         else
           flag[2] <= 1'b1;
      end
      else if (detect_edge_idle_r6 == 1'b1 || idelay_inc_idle_r6 == 1'b1 ||
               idelay_rst_idle_r6 == 1'b1) begin
         if (curr_dqs_level != prev_dqs_level)
           flag[3] <= 1'b0;
         else
           flag[3] <= 1'b1;
      end
   end

   // First and second edge detection logic
   always @ (posedge CLK) begin
      if (reset_int == 1'b1) begin
         transition[1:0] <= 2'b00;
      end
      else if ((dly_after_first_cnt == 4'b0000) && (state[2:0] == detect_edge)&&
               ((flag[3:0] == 4'h0) || (flag[3:0] == 4'hF))) begin
         if ((curr_dqs_level != prev_dqs_level) && (transition_rst == 1'b0) &&
             (tap_counter > 6'b000000) ) begin
            transition[1:0] <= transition[1:0] + 1'b1;
         end
      end
      else if (transition_rst == 1'b1)
        transition[1:0] <= 2'b00;
      else
        transition[1:0] <= transition[1:0];
   end

   always @ (posedge CLK) begin
      if (reset_int == 1'b1) begin
         transition_rst  <= 1'b0;
         first_edge      <= 1'b0;
         second_edge     <= 1'b0;
      end
      else begin
         case (transition[1:0])
           2'b01: begin
              first_edge <= 1'b1;
           end
           2'b10: begin
              if (transition_rst == 1'b1)
                begin
                   second_edge <= 1'b0;
                   transition_rst <= 1'b0;
                end
              else
                begin
                   second_edge    <= 1'b1;
                   transition_rst <= 1'b1;
                end
           end
           default: begin
              first_edge     <= 1'b0;
              second_edge    <= 1'b0;
           end
         endcase
      end
   end

   // State Machine for edge detection and midpoint determination
   always @ (posedge CLK) begin
      if (reset_int == 1'b1) begin   // DQS IDELAY in reset
         dly_rst           <= 1'b1;
         dly_ce            <= 1'b0;
         dly_inc           <= 1'b0;
         idelay_rst_idle   <= 1'b0;
         detect_edge_idle  <= 1'b0;
         idelay_inc_idle   <= 1'b0;
         prev_dqs_level    <= curr_dqs_level;
         state[2:0]        <= idelay_rst;
      end
      else if ((CTRL_DUMMYREAD_START == 1'b1) && (sel_complete == 1'b0)) begin
         case (state[2:0])
           3'b000: begin // idelay_rst
              dly_rst         <= 1'b1;
              dly_ce          <= 1'b0;
              dly_inc         <= 1'b0;
              idelay_rst_idle <= 1'b1;
              state[2:0]      <= idle;
           end
           3'b001: begin // idle
              dly_rst          <= 1'b0;
              dly_ce           <= 1'b0;
              dly_inc          <= 1'b0;
              idelay_rst_idle  <= 1'b0;
              detect_edge_idle <= 1'b0;
              idelay_inc_idle  <= 1'b0;
              if (idelay_rst_idle_r5 == 1'b1)
                state[2:0] <= idelay_inc;
              else if ((idelay_inc_idle_r6 == 1'b1) ||
                       ((detect_edge_idle_r6 == 1'b1) && (second_edge_r2== 1'b0)
                && (tap_counter[5:0] != 6'b111111)))//changed from _r5 to _r6
              state[2:0] <= detect_edge;
              else
                state[2:0] <= idle;
           end
           3'b010: begin // idelay_inc
              dly_rst         <= 1'b0;
              dly_ce          <= 1'b1;
              dly_inc         <= 1'b1;
              idelay_inc_idle <= 1'b1;
              state[2:0]      <= idle;
              if((flag[3:0] == 4'h0) || (flag[3:0] == 4'hF))
                prev_dqs_level   <= curr_dqs_level;
              else
                prev_dqs_level   <= prev_dqs_level;
           end
           3'b011: begin // detect_edge
              dly_rst          <= 1'b0;
              dly_ce           <= 1'b1;
              dly_inc          <= 1'b1;
              detect_edge_idle <= 1'b1;
              state[2:0]       <= idle;
              if((flag[3:0] == 4'h0) || (flag[3:0] == 4'hF))
                prev_dqs_level   <= curr_dqs_level;
              else
                prev_dqs_level   <= prev_dqs_level;
           end
           default: begin
              dly_rst          <= 1'b0;
              dly_ce           <= 1'b0;
              dly_inc          <= 1'b0;
              idelay_rst_idle  <= 1'b0;
              detect_edge_idle <= 1'b0;
              idelay_inc_idle  <= 1'b0;
              prev_dqs_level   <= curr_dqs_level;
              state[2:0]       <= idle;
           end
         endcase
      end
      else
        begin
           dly_rst          <= 1'b0;
           dly_ce           <= 1'b0;
           dly_inc          <= 1'b0;
           idelay_rst_idle  <= 1'b0;
           detect_edge_idle <= 1'b0;
           idelay_inc_idle  <= 1'b0;
           prev_dqs_level   <= curr_dqs_level;
           state[2:0]       <= idelay_rst;
        end
   end


endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -