Verilog設(shè)計實例(2)一步一步實現(xiàn)一個多功能通用計數(shù)器

寫在前面

相關(guān)博文
博客首頁
注:學(xué)習(xí)交流使用!

正文

多功能計數(shù)器司草,英文名為:Versatile Counter没陡;所謂多功能,這里包括二進制計數(shù)番甩,格雷碼計數(shù)以及線性反饋移位寄存器(LFSR)三種畴蒲,本文通過從普通的計數(shù)器開始,也就是單個功能的計數(shù)器開始对室,一步一步過渡到多功能計數(shù)器模燥。
作為對以下相關(guān)博文的延伸練習(xí):
Verilog設(shè)計實例(1)線性反饋移位寄存器(LFSR)
FPGA設(shè)計心得(8)Verilog中的編譯預(yù)處理語句

普通的二進制計數(shù)器

這個作為開頭,不必多說掩宜,計數(shù)就完事了蔫骂。

電路設(shè)計

設(shè)計文件:

`timescale 1ns/1ps
//////////////////////////////////////////////////////////////////////////////////
// Engineer: Reborn Lee
// Module Name: binary counter
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module binary_counter#(parameter N_BITS = 4)(
    input i_clk,
    input i_rst,
    output [N_BITS - 1 : 0] o_cnt,
    output o_cnt_done
    );

    reg [N_BITS - 1 : 0] bin_cnt = 0;
    always@(posedge i_clk) begin
        if(i_rst) begin
            bin_cnt <= 0;
        end
        else begin
            bin_cnt <= bin_cnt + 1;
        end
    end

    assign o_cnt_done = (bin_cnt == 0)? 1:0;
    assign o_cnt = bin_cnt;


endmodule

行為仿真

tb文件:

`timescale 1ns/1ps
module bin_cnt_tb;

    parameter N_BITS = 4;
    reg i_clk;
    reg i_rst;
    wire [N_BITS - 1 : 0] o_cnt;
    wire o_cnt_done;

    initial begin
        i_clk = 0;
        forever begin
            # 2 i_clk = ~ i_clk;
        end
    end

    initial begin
        i_rst = 1;

        # 8
        i_rst = 0;

    end

    binary_counter #(.N_BITS(N_BITS))
    inst_bin_cnt(
        .i_rst(i_rst),
        .i_clk(i_clk),
        .o_cnt(o_cnt),
        .o_cnt_done(o_cnt_done)
        );
endmodule

仿真圖:

普通二進制計數(shù)器仿真波形

普通的格雷碼計數(shù)器

任意位寬的格雷碼計數(shù)器,實現(xiàn)的方式通常是設(shè)計一個普通的二進制計數(shù)器牺汤,同時將計數(shù)結(jié)果轉(zhuǎn)化為格雷碼辽旋。
二進制與格雷碼的轉(zhuǎn)換方式,詳情見:格雷碼和二進制轉(zhuǎn)換檐迟。
為了方便給出原理圖:

二進制轉(zhuǎn)格雷碼原理圖

偽代碼描述為:

assign gray_value = binary_value ^ (binary_value>>1);

或者:

assign gray_cnt = { bin_cnt[N_BITS - 1], bin_cnt[N_BITS - 1 : 1]^bin_cnt[N_BITS - 2 : 0]};

電路設(shè)計

一種簡單的設(shè)計方式為:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Engineer: Reborn Lee
// Create Date: 2020/06/02 13:46:10
// Module Name: gray_counter
// Additional Comments: common gray counter
// 
//////////////////////////////////////////////////////////////////////////////////


module gray_counter #(parameter N_BITS = 4)(
    input i_clk,
    input i_rst,
    output [N_BITS - 1 : 0] o_cnt,
    output o_cnt_done
    );
    
    reg [N_BITS - 1 : 0] bin_cnt = 0;
    reg [N_BITS - 1 : 0] gray_cnt;
    always@(posedge i_clk) begin
        if(i_rst) begin
            bin_cnt <= 0;
            gray_cnt <= 0;
        end
        else begin
            bin_cnt <= bin_cnt + 1;
            // translate binary counter into  gray counter  
            gray_cnt <= bin_cnt ^ bin_cnt >>> 1; 

            //or 
            // gray_cnt <= { bin_cnt[N_BITS - 1], bin_cnt[N_BITS - 1 : 1]^bin_cnt[N_BITS - 2 : 0]};

            //or 

            // for(int i = 0; i < N_BITS - 1; i = i + 1) begin
            //  gray_cnt[i] <= bin_cnt[i+1]^bin_cnt[i];
            // end
            // gray_cnt[N_BITS - 1] <= bin_cnt[N_BITS - 1];

        end

    end

    assign o_cnt = gray_cnt;
    // or 
    assign o_cnt_done = (gray_cnt == 0) ? 1 : 0;



    
endmodule

注釋部分解釋:

            for(int i = 0; i < N_BITS - 1; i = i + 1) begin
                gray_cnt[i] <= bin_cnt[i+1]^bin_cnt[i];
            end
            gray_cnt[N_BITS - 1] <= bin_cnt[N_BITS - 1];

以及:

gray_cnt <= { bin_cnt[N_BITS - 1], bin_cnt[N_BITS - 1 : 1]^bin_cnt[N_BITS - 2 : 0]};

均在always塊內(nèi)补胚,因此使用非阻塞賦值。
又和二進制計數(shù)在一起always內(nèi)追迟,且緊鄰分布溶其,因此計數(shù)相較于二進制慢一拍,但毫無影響(不影響計數(shù)總數(shù))敦间。

注: 三種二進制轉(zhuǎn)換為格雷碼的實現(xiàn)原理一致瓶逃,效果等價。

行為仿真

TestBench設(shè)計:

`timescale 1ns/1ps
module gray_cnt_tb;

    parameter N_BITS = 4;
    reg i_clk;
    reg i_rst;
    wire [N_BITS - 1 : 0] o_cnt;
    wire o_cnt_done;

    initial begin
        i_clk = 0;
        forever begin
            # 2 i_clk = ~ i_clk;
        end
    end

    initial begin
        i_rst = 1;

        # 8
        i_rst = 0;

    end

    gray_counter #(.N_BITS(N_BITS))
    inst_gray_cnt(
        .i_rst(i_rst),
        .i_clk(i_clk),
        .o_cnt(o_cnt),
        .o_cnt_done(o_cnt_done)
        );
endmodule

行為仿真波形:


格雷碼計數(shù)器仿真波形

局部放大:


局部放大

局部放大

LFSR

這個請參考上篇博文廓块,單獨做了一篇博客:
Verilog設(shè)計實例(1)線性反饋移位寄存器(LFSR)

為了方便不跳轉(zhuǎn)另外一個鏈接厢绝,這里給出設(shè)計:

電路設(shè)計

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Engineer: Reborn Lee
// Create Date: 2020/06/01 12:50:38
// Module Name: lfsr
//////////////////////////////////////////////////////////////////////////////////


module lfsr #(parameter NUM_BITS = 3)(
   input i_Clk,
   input i_Enable,
 
   // data valid
   input i_Seed_DV,

   // Optional Seed Value
   input [NUM_BITS-1:0] i_Seed_Data,
 
   output [NUM_BITS-1:0] o_LFSR_Data,
   output o_LFSR_Done

    );

  // internal variables
  reg [NUM_BITS:1] r_LFSR = 0;
  reg              r_XNOR;
 
 
  // Purpose: Load up LFSR with Seed if Data Valid (DV) pulse is detected.
  // Othewise just run LFSR when enabled.
    always @(posedge i_Clk)
    begin
      if (i_Enable == 1'b1)
      begin
          if (i_Seed_DV == 1'b1)
            r_LFSR <= i_Seed_Data;
          else
            r_LFSR <= {r_LFSR[NUM_BITS-1:1],r_XNOR}; //left right
      end
    end

// Create Feedback Polynomials.  Based on Application Note:
  // http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
    always @(*)
    begin
      case (NUM_BITS)
        3: begin
          r_XNOR = r_LFSR[3] ^~ r_LFSR[2];
        end
        4: begin
          r_XNOR = r_LFSR[4] ^~ r_LFSR[3];
        end
        5: begin
          r_XNOR = r_LFSR[5] ^~ r_LFSR[3];
        end
        6: begin
          r_XNOR = r_LFSR[6] ^~ r_LFSR[5];
        end
        7: begin
          r_XNOR = r_LFSR[7] ^~ r_LFSR[6];
        end
        8: begin
          r_XNOR = r_LFSR[8] ^~ r_LFSR[6] ^~ r_LFSR[5] ^~ r_LFSR[4];
        end
        9: begin
          r_XNOR = r_LFSR[9] ^~ r_LFSR[5];
        end
        10: begin
          r_XNOR = r_LFSR[10] ^~ r_LFSR[7];
        end
        11: begin
          r_XNOR = r_LFSR[11] ^~ r_LFSR[9];
        end
        12: begin
          r_XNOR = r_LFSR[12] ^~ r_LFSR[6] ^~ r_LFSR[4] ^~ r_LFSR[1];
        end
        13: begin
          r_XNOR = r_LFSR[13] ^~ r_LFSR[4] ^~ r_LFSR[3] ^~ r_LFSR[1];
        end
        14: begin
          r_XNOR = r_LFSR[14] ^~ r_LFSR[5] ^~ r_LFSR[3] ^~ r_LFSR[1];
        end
        15: begin
          r_XNOR = r_LFSR[15] ^~ r_LFSR[14];
        end
        16: begin
          r_XNOR = r_LFSR[16] ^~ r_LFSR[15] ^~ r_LFSR[13] ^~ r_LFSR[4];
          end
        17: begin
          r_XNOR = r_LFSR[17] ^~ r_LFSR[14];
        end
        18: begin
          r_XNOR = r_LFSR[18] ^~ r_LFSR[11];
        end
        19: begin
          r_XNOR = r_LFSR[19] ^~ r_LFSR[6] ^~ r_LFSR[2] ^~ r_LFSR[1];
        end
        20: begin
          r_XNOR = r_LFSR[20] ^~ r_LFSR[17];
        end
        21: begin
          r_XNOR = r_LFSR[21] ^~ r_LFSR[19];
        end
        22: begin
          r_XNOR = r_LFSR[22] ^~ r_LFSR[21];
        end
        23: begin
          r_XNOR = r_LFSR[23] ^~ r_LFSR[18];
        end
        24: begin
          r_XNOR = r_LFSR[24] ^~ r_LFSR[23] ^~ r_LFSR[22] ^~ r_LFSR[17];
        end
        25: begin
          r_XNOR = r_LFSR[25] ^~ r_LFSR[22];
        end
        26: begin
          r_XNOR = r_LFSR[26] ^~ r_LFSR[6] ^~ r_LFSR[2] ^~ r_LFSR[1];
        end
        27: begin
          r_XNOR = r_LFSR[27] ^~ r_LFSR[5] ^~ r_LFSR[2] ^~ r_LFSR[1];
        end
        28: begin
          r_XNOR = r_LFSR[28] ^~ r_LFSR[25];
        end
        29: begin
          r_XNOR = r_LFSR[29] ^~ r_LFSR[27];
        end
        30: begin
          r_XNOR = r_LFSR[30] ^~ r_LFSR[6] ^~ r_LFSR[4] ^~ r_LFSR[1];
        end
        31: begin
          r_XNOR = r_LFSR[31] ^~ r_LFSR[28];
        end
        32: begin
          r_XNOR = r_LFSR[32] ^~ r_LFSR[22] ^~ r_LFSR[2] ^~ r_LFSR[1];
        end
 
      endcase // case (NUM_BITS)
    end // always @ (*)

    assign o_LFSR_Data = r_LFSR[NUM_BITS:1];
 
    // Conditional Assignment (?)
    assign o_LFSR_Done = (r_LFSR[NUM_BITS:1] == i_Seed_Data) ? 1'b1 : 1'b0;


endmodule


行為仿真

`timescale 1ns / 1ps
module lfsr_tb ();
 
  parameter c_NUM_BITS = 4;
   
  reg r_Clk = 1'b0;
   
  wire [c_NUM_BITS-1:0] w_LFSR_Data;
  wire w_LFSR_Done;
   
  lfsr #(.NUM_BITS(c_NUM_BITS)) LFSR_inst
         (.i_Clk(r_Clk),
          .i_Enable(1'b1),
          .i_Seed_DV(1'b0),
          .i_Seed_Data({c_NUM_BITS{1'b0}}), // Replication
          .o_LFSR_Data(w_LFSR_Data),
          .o_LFSR_Done(w_LFSR_Done)
          );
  
  always @(*)
    #10 r_Clk <= ~r_Clk; 
   
endmodule // LFSR_TB

仿真波形:


LFSR仿真波形

多功能計數(shù)器

有了上面三種計數(shù)器的單獨設(shè)計,下面該考慮組合起來了带猴,是用什么樣的方式組合昔汉?
用戶可以選擇,可以通過定義條件編譯的方式拴清,定義了某個宏就執(zhí)行某種計數(shù)器靶病,計數(shù)位寬可選擇,通過參數(shù)化的方式實現(xiàn)贷掖。

電路設(shè)計

本設(shè)計用到了上面的三個模塊嫡秕,例化到本模塊使用;

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Create Date: 2020/06/02 16:22:52
// Module Name: versatile_counter
//////////////////////////////////////////////////////////////////////////////////

// `define LFSR_MACRO
`define GRAY
// `define BIN
module versatile_counter #(parameter N_BITS = 4)(
    input i_clk,
    input i_rst,
    output [N_BITS - 1 : 0] o_out,
    output o_out_done

    );

    `ifdef LFSR_MACRO

    lfsr #(.NUM_BITS(N_BITS)) LFSR_inst
         (.i_Clk(i_clk),
          .i_Enable(1'b1),
          .i_Seed_DV(1'b0),
          .i_Seed_Data({N_BITS{1'b0}}), // Replication
          .o_LFSR_Data(o_out),
          .o_LFSR_Done(o_out_done)
          );


    `elsif GRAY

    gray_counter #(.N_BITS(N_BITS))
    inst_gray_cnt(
        .i_rst(i_rst),
        .i_clk(i_clk),
        .o_cnt(o_out),
        .o_cnt_done(o_out_done)
        );


    `else
    binary_counter #(.N_BITS(N_BITS))
    inst_bin_cnt(
        .i_rst(i_rst),
        .i_clk(i_clk),
        .o_cnt(o_out),
        .o_cnt_done(o_out_done)
        );

    `endif


endmodule

這里約定定義了宏GRAY苹威,就是跑格雷碼的代碼,定義了宏BIN驾凶,就是跑二進制的代碼牙甫,定義了LFSR_MACRO掷酗,就是跑LFSR的程序。

行為仿真

先假設(shè)定義了宏GRAY窟哺,仿真程序通用泻轰,如下:

`timescale 1ns/1ps
module sim_versatile_counter;

    parameter N_BITS = 4;
    reg i_clk;
    reg i_rst;
    wire [N_BITS - 1 : 0] o_out;
    wire o_out_done;

    initial begin
        i_clk = 0;
        forever begin
            # 2 i_clk = ~ i_clk;
        end
    end

    initial begin
        i_rst = 1;

        # 8
        i_rst = 0;

    end

    versatile_counter #(.N_BITS(N_BITS))
    inst_vc(
        .i_rst(i_rst),
        .i_clk(i_clk),
        .o_out(o_out),
        .o_out_done(o_out_done)
        );
endmodule

仿真波形 :

格雷碼計數(shù)器

確實是格雷碼計數(shù)器 ,放大:


局部放大
局部放大

如果定義了宏BIN且轨,

// `define LFSR_MACRO
// `define GRAY
`define BIN

則仿真圖如下:


二進制計數(shù)器

放大觀測:

局部放大

局部放大

如果定義了宏LFSR_MACRO浮声,則輸出LFSR計數(shù):

 `define LFSR_MACRO
// `define GRAY
//`define BIN
LFSR

局部放大
局部放大

生成語句實現(xiàn)方式

這里使用生成語句,generate case來實現(xiàn)多功能計數(shù)器旋奢,我們需要定義一個參數(shù)SEL泳挥,當(dāng)SEL為0的時候,輸出為LFSR至朗;當(dāng)SEL為1時屉符,輸出為格雷碼計數(shù)器;當(dāng)SEL為2時候锹引,輸出為二進制計數(shù)器矗钟。

電路設(shè)計

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Create Date: 2020/06/02 16:22:52
// Design Name: 
// Module Name: versatile_counter
// Revision 0.01 - File Created
// Additional Comments:
// Reborn Lee
//////////////////////////////////////////////////////////////////////////////////
module versatile_counter #(
    parameter N_BITS = 4,
    parameter SEL = 0

    )(
    input i_clk,
    input i_rst,
    output [N_BITS - 1 : 0] o_out,
    output o_out_done

    );


generate

    case(SEL)

        0: begin
            lfsr #(.NUM_BITS(N_BITS)) LFSR_inst
         (.i_Clk(i_clk),
          .i_Enable(1'b1),
          .i_Seed_DV(1'b0),
          .i_Seed_Data({N_BITS{1'b0}}), // Replication
          .o_LFSR_Data(o_out),
          .o_LFSR_Done(o_out_done)
          );
        end
        1: begin
            gray_counter #(.N_BITS(N_BITS))
        inst_gray_cnt(
        .i_rst(i_rst),
        .i_clk(i_clk),
        .o_cnt(o_out),
        .o_cnt_done(o_out_done)
        );
        end
        2: begin
            binary_counter #(.N_BITS(N_BITS))
        inst_bin_cnt(
        .i_rst(i_rst),
        .i_clk(i_clk),
        .o_cnt(o_out),
        .o_cnt_done(o_out_done)
        );

        end


    endcase

endgenerate



endmodule

行為仿真

SEL為0,也即LFSR:
仿真文件例化改為:

    versatile_counter #(
        .N_BITS(N_BITS),
        .SEL(0)
        )
    inst_vc(
        .i_rst(i_rst),
        .i_clk(i_clk),
        .o_out(o_out),
        .o_out_done(o_out_done)
        );
LFSR

放大:


局部放大

局部放大

局部放大

SEL為1嫌变,也即格雷碼計數(shù)器:
仿真文件例化改為:

    versatile_counter #(
        .N_BITS(N_BITS),
        .SEL(1)
        )
    inst_vc(
        .i_rst(i_rst),
        .i_clk(i_clk),
        .o_out(o_out),
        .o_out_done(o_out_done)
        );
格雷碼計數(shù)器

放大:


局部放大

局部放大

SEL為2吨艇,也即 二進制計數(shù)器:

仿真文件例化改為:

    versatile_counter #(
        .N_BITS(N_BITS),
        .SEL(2)
        )
    inst_vc(
        .i_rst(i_rst),
        .i_clk(i_clk),
        .o_out(o_out),
        .o_out_done(o_out_done)
        );
二進制計數(shù)器

放大:


局部放大

局部放大

注意事項

關(guān)于多功能計數(shù)器的注意事項,這里不做多說腾啥,
在debug的過程中秸应,可以先進行elaborated design,

RTL檢測

如果沒有錯誤,在進行行為仿真碑宴;
其次需要注意软啼,在宏定義過程中,別忘了`這個符號延柠。
就這樣吧祸挪,感覺如此實現(xiàn)也不是太難,我還記得使用OPENCORES里的那個設(shè)計實例贞间,編譯預(yù)處理指令一大堆贿条,看得我頭皮發(fā)麻,最關(guān)鍵的是我還沒編譯通過增热。

工程要不要分享了呢整以?暫時算了吧,反正代碼已經(jīng)貼出來了峻仇,實在需要的可以說一聲公黑。
工具 :vivado 2019.1

參考資料

參考資料1
參考資料2
參考資料3

交個朋友

個人微信公眾號:FPGA LAB
FPGA/IC技術(shù)交流2020

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子凡蚜,更是在濱河造成了極大的恐慌人断,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朝蜘,死亡現(xiàn)場離奇詭異恶迈,居然都是意外死亡,警方通過查閱死者的電腦和手機谱醇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門暇仲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人副渴,你說我怎么就攤上這事奈附。” “怎么了佳晶?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵桅狠,是天一觀的道長。 經(jīng)常有香客問我轿秧,道長中跌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任菇篡,我火速辦了婚禮漩符,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘驱还。我一直安慰自己嗜暴,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布议蟆。 她就那樣靜靜地躺著闷沥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪咐容。 梳的紋絲不亂的頭發(fā)上舆逃,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音戳粒,去河邊找鬼路狮。 笑死,一個胖子當(dāng)著我的面吹牛蔚约,可吹牛的內(nèi)容都是我干的奄妨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼苹祟,長吁一口氣:“原來是場噩夢啊……” “哼砸抛!你這毒婦竟也來了评雌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤锰悼,失蹤者是張志新(化名)和其女友劉穎柳骄,沒想到半個月后团赏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箕般,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年舔清,在試婚紗的時候發(fā)現(xiàn)自己被綠了丝里。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡体谒,死狀恐怖杯聚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抒痒,我是刑警寧澤幌绍,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站故响,受9級特大地震影響傀广,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜彩届,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一伪冰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧樟蠕,春花似錦贮聂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至靡狞,卻和暖如春耻警,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耍攘。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工榕栏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蕾各。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓扒磁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親式曲。 傳聞我的和親對象是個殘疾皇子妨托,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348