MyFPGA Forum

 找回密码
 注册
搜索
查看: 4343|回复: 0

时序式设计出来的实例 : (encoder 端)

[复制链接]
发表于 2010-4-6 23:45:41 | 显示全部楼层 |阅读模式
这边简单举个例子, 我们在规划 FPGA 时, 有时因为 pin 脚数不够使用, 或希望保留多些 pin 脚留作他用等因素, 会把原本需要比较多 port 的沟通接口, 化简为类似 I2C 的传输方式.. 又传输的资料没有需要像 I2C 一样多或复杂, 这时可以依我们的需求来规划这边的架构, 以下传输端的架构因而产生
(这边是先规划 block diagram => timing diagram => coding => simulation 看是不是符合所想要的时序)

module ext_pll_ctrl
(
    // system input
    osc_50,               
    rstn,
    // device 1
    clk1_set_wr,
    clk1_set_rd,
    // device 2
    clk2_set_wr,
    clk2_set_rd,
    // device 3
    clk3_set_wr,
    clk3_set_rd,
    // setting trigger
    conf_wr, // 1T 50MHz
    conf_rd, // 1T 50MHz
    // status
    conf_ready,
    rd_data_ready, // 1T 50MHz
    // 2-wire interface
    max_sclk,
    max_sdat
);


//=======================================================
//  Port declarations
//=======================================================
// system input
input           osc_50;               
input           rstn;
// device 1
input     [3:0] clk1_set_wr;
output    [3:0] clk1_set_rd;
// device 2
input     [3:0] clk2_set_wr;
output    [3:0] clk2_set_rd;
// device 3
input     [3:0] clk3_set_wr;
output    [3:0] clk3_set_rd;
// setting trigger
input           conf_wr;
input           conf_rd;
// status
output          conf_ready;
output          rd_data_ready;
// 2-wire interface
output          max_sclk;
inout           max_sdat;


//=======================================================
//  Parameter declarations
//=======================================================


//=======================================================
//  Signal declarations
//=======================================================
reg            conf_ready;
reg            rd_data_ready;
reg            conf_wr_p2s;
wire    [13:0] conf_data;
reg      [4:0] conf_counter;
reg            conf_end;
reg            p2s;
reg            s2p_act_pre;
reg      [1:0] s2p_act;
reg     [11:0] s2p;
reg            sclk;
reg            sclk_mask;


//=======================================================
//  Structural coding
//=======================================================
assign clk1_set_rd = s2p[3:0];
assign clk2_set_rd = s2p[7:4];
assign clk3_set_rd = s2p[11:8];
assign max_sclk = sclk || (sclk_mask ? ~osc_50 : 1'b0);
assign max_sdat = (s2p_act_pre || s2p_act[1]) ? 1'bz : p2s;
assign conf_data = conf_wr_p2s ? {2'b10, clk3_set_wr, clk2_set_wr, clk1_set_wr} : 14'hfff;


//--- config status ---//
always @ (posedge osc_50 or negedge rstn)
        if(!rstn)
                conf_ready <= 1'b1;
        else if (conf_wr || conf_rd)
        begin
                conf_ready <=        1'b0;
                conf_wr_p2s <= conf_wr;
        end
        else if (conf_end)
                conf_ready <=        1'b1;

//--- config counter ---//
always @ (posedge osc_50 or negedge rstn)
        if(!rstn)
                conf_counter <= 5'b0;
        else if (conf_ready)
                conf_counter <= 5'b0;
        else
                conf_counter <= conf_counter + 1;

//--- p2s convert ---//
always @ (posedge osc_50 or negedge rstn)
  if (!rstn)
  begin
          sclk <= 1'b1; p2s <= 1'b1; sclk_mask <= 1'b0; conf_end <= 1'b0; s2p_act_pre <= 1'b0;
  end
  else
    case (conf_counter)
            5'd1    : p2s <= 1'b0;
            5'd2    : sclk <= 1'b0;
            5'd3    : begin p2s <= conf_data[13]; sclk_mask <= 1'b1; end
            5'd4    : begin p2s <= conf_data[12]; s2p_act_pre <= !conf_wr_p2s; end
            5'd5    : p2s <= conf_data[11];
            5'd6    : p2s <= conf_data[10];
            5'd7    : p2s <= conf_data[9];
            5'd8    : p2s <= conf_data[8];
            5'd9    : p2s <= conf_data[7];
            5'd10   : p2s <= conf_data[6];
            5'd11   : p2s <= conf_data[5];
            5'd12   : p2s <= conf_data[4];
            5'd13   : p2s <= conf_data[3];
            5'd14   : p2s <= conf_data[2];
            5'd15   : p2s <= conf_data[1];
            5'd16   : begin p2s <= conf_data[0]; s2p_act_pre <= 1'b0; end
      5'd17   : begin sclk <= 1'b0; p2s <= 1'b0; sclk_mask <= 1'b0; end       
      5'd18   : sclk <= 1'b1;
      5'd19   : begin p2s <= 1'b1; conf_end <= 1'b1; end
            default : begin sclk <= 1'b1; p2s <= 1'b1; sclk_mask <= 1'b0; conf_end <= 1'b0; s2p_act_pre <= 1'b0; end
    endcase

//--- s2p convert ---//
always @ (posedge max_sclk)
        if (s2p_act[0])
    s2p <= {s2p[10:0], max_sdat};

always @ (posedge osc_50 or negedge rstn)
  if (!rstn)
  begin
          s2p_act <= 2'b0;
    rd_data_ready <= 1'b0;
  end
  else
  begin
          s2p_act <= {s2p_act[0], s2p_act_pre};
    if (s2p_act[1] && !s2p_act[0])
            rd_data_ready <= 1'b1;
    else
      rd_data_ready <= 1'b0;
  end

endmodule
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|MyFPGA

GMT+8, 2024-3-29 05:50 , Processed in 0.033124 second(s), 15 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表