SHARE
TWEET

Untitled

a guest Feb 23rd, 2014 86 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. `define MEM_MINWIDTH 5
  2. `define MEM_MAXWIDTH 15
  3.  
  4. `define DSP_A_MAXWIDTH 25
  5. `define DSP_B_MAXWIDTH 18
  6.  
  7. module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
  8.         parameter MEMID = "";
  9.         parameter SIZE = 256;
  10.         parameter OFFSET = 0;
  11.         parameter ABITS = 8;
  12.         parameter WIDTH = 8;
  13.  
  14.         parameter RD_PORTS = 1;
  15.         parameter RD_CLK_ENABLE = 1'b1;
  16.         parameter RD_CLK_POLARITY = 1'b1;
  17.         parameter RD_TRANSPARENT = 1'b1;
  18.  
  19.         parameter WR_PORTS = 1;
  20.         parameter WR_CLK_ENABLE = 1'b1;
  21.         parameter WR_CLK_POLARITY = 1'b1;
  22.  
  23.         input [RD_PORTS-1:0] RD_CLK;
  24.         input [RD_PORTS*ABITS-1:0] RD_ADDR;
  25.         output reg [RD_PORTS*WIDTH-1:0] RD_DATA;
  26.  
  27.         input [WR_PORTS-1:0] WR_CLK, WR_EN;
  28.         input [WR_PORTS*ABITS-1:0] WR_ADDR;
  29.         input [WR_PORTS*WIDTH-1:0] WR_DATA;
  30.  
  31.         wire [1023:0] _TECHMAP_DO_ = "proc; clean";
  32.  
  33.         parameter _TECHMAP_CONNMAP_RD_CLK_ = 0;
  34.         parameter _TECHMAP_CONNMAP_WR_CLK_ = 0;
  35.         parameter _TECHMAP_CONNMAP_RD_ADDR_ = 0;
  36.         parameter _TECHMAP_CONNMAP_WR_ADDR_ = 0;
  37.         parameter _TECHMAP_CONNMAP_RD_PORTS_ = 0;
  38.         parameter _TECHMAP_CONNMAP_WR_PORTS_ = 0;
  39.  
  40.  
  41.         reg _TECHMAP_FAIL_;
  42.         initial begin
  43.                 _TECHMAP_FAIL_ <= 0;
  44.  
  45.                 // only map cells with only one read and one write port
  46.                 if (RD_PORTS > 2 || WR_PORTS > 2)
  47.                         _TECHMAP_FAIL_ <= 1;
  48.  
  49.                 // we expect positive read clock and non-transparent reads
  50.                 if (RD_TRANSPARENT || !RD_CLK_ENABLE || !RD_CLK_POLARITY)
  51.                         _TECHMAP_FAIL_ <= 1;
  52.  
  53.                 // we expect positive write clock
  54.                 if (!WR_CLK_ENABLE || !WR_CLK_POLARITY)
  55.                         _TECHMAP_FAIL_ <= 1;
  56.  
  57.                 // read and write must be in same clock domain
  58.                 if (_TECHMAP_CONNMAP_RD_CLK_ != _TECHMAP_CONNMAP_WR_CLK_)
  59.                         _TECHMAP_FAIL_ <= 1;
  60.  
  61.                 // we don't do small memories or memories with offsets
  62.                 if (OFFSET != 0 || ABITS < `MEM_MINWIDTH || SIZE < 2**`MEM_MINWIDTH)
  63.                         _TECHMAP_FAIL_ <= 1;
  64.  
  65.                 if (_TECHMAP_CONNMAP_RD_ADDR_ != _TECHMAP_CONNMAP_WR_ADDR_)
  66.                         _TECHMAP_FAIL_ <= 1;
  67.         end
  68.  
  69.         genvar i;
  70.         generate
  71.                 for (i = 0; i < WIDTH; i=i+1) begin:slice
  72.                         if (RD_PORTS > 1 || WR_PORTS > 1) begin
  73.                                 \$__mem_Wx1_dp_generator #(
  74.                                         .ABITS(ABITS),
  75.                                         .SIZE(SIZE),
  76.                                 ) bit_slice (
  77.                                 .CLK(RD_CLK),
  78.                                 .RD_ADDR(RD_ADDR),
  79.                                 .RD_DATA(RD_DATA[RD_PORTS*(i+1)-1:RD_PORTS*i]),
  80.                                 .WR_ADDR(WR_ADDR),
  81.                                 .WR_DATA(WR_DATA[WD_PORTS*(i+1)-1:WD_PORTS*i]),
  82.                                 .WR_EN(WR_EN)
  83.                                 );
  84.                         end
  85.                         else begin
  86.                                 \$__mem_Wx1_sp_generator #(
  87.                                         .ABITS(ABITS),
  88.                                         .SIZE(SIZE),
  89.                                 ) bit_slice (
  90.                                 .CLK(RD_CLK),
  91.                                 .RD_ADDR(RD_ADDR),
  92.                                 .RD_DATA(RD_DATA[i]),
  93.                                 .WR_ADDR(WR_ADDR),
  94.                                 .WR_DATA(WR_DATA[i]),
  95.                                 .WR_EN(WR_EN)
  96.                                 );
  97.                         end            
  98.                 end
  99.         endgenerate
  100. endmodule
  101.  
  102. module \$__mem_Wx1_dp_generator (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN);
  103.         parameter ABITS = 4;
  104.         parameter SIZE = 16;
  105.  
  106.         input CLK;
  107.         input [1:0] WR_EN, WR_DATA;
  108.         input [2*ABITS-1:0] RD_ADDR, WR_ADDR;
  109.         output [1:0] RD_DATA;
  110.  
  111.         wire [1023:0] _TECHMAP_DO_ = "proc; clean";
  112.  
  113.         generate
  114.           if (ABITS > `MEM_MAXWIDTH) begin
  115.                 wire [1:0] high_rd_data, low_rd_data;
  116.                 if (SIZE > 2**(ABITS-1)) begin
  117.                         \$__mem_Wx1_dp_generator #(
  118.                                 .ABITS(ABITS-1),
  119.                                 .SIZE(SIZE - 2**(ABITS-1)),
  120.                         ) part_high (
  121.                                 .CLK(CLK),
  122.                                 .RD_ADDR(RD_ADDR[ABITS-2:0]),
  123.                                 .RD_DATA(high_rd_data),
  124.                                 .WR_ADDR(WR_ADDR[ABITS-2:0]),
  125.                                 .WR_DATA(WR_DATA),
  126.                                 .WR_EN(WR_EN && WR_ADDR[ABITS-1])
  127.                         );
  128.                 end else begin
  129.                         assign high_rd_data = 2'bxx;
  130.                 end
  131.                 \$__mem_Wx1_dp_generator #(
  132.                         .ABITS(ABITS-1),
  133.                         .SIZE(SIZE > 2**(ABITS-1) ? 2**(ABITS-1) : SIZE),
  134.                 ) part_low (
  135.                         .CLK(CLK),
  136.                         .RD_ADDR(RD_ADDR[ABITS-2:0]),
  137.                         .RD_DATA(low_rd_data),
  138.                         .WR_ADDR(WR_ADDR[ABITS-2:0]),
  139.                         .WR_DATA(WR_DATA),
  140.                         .WR_EN(WR_EN && !WR_ADDR[ABITS-1])
  141.                 );
  142.                 reg delayed_abit;
  143.                 always @(posedge CLK)
  144.                         delayed_abit <= RD_ADDR[ABITS-1];
  145.                 assign RD_DATA = delayed_abit ? high_rd_data : low_rd_data;
  146.           end else begin
  147.                 dual_port_ram _TECHMAP_REPLACE_ (
  148.                         .clk(CLK),
  149.                         .addr1({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR[ABITS-1:0] }),
  150.                         .addr1__U({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR[ABITS-1:0] }),
  151.                         .data1(RD_DATA[0]),
  152.                         .out1(WR_DATA[0]),
  153.                         .we1({ {8}{WR_EN[0]} }),
  154.                         .we1__U({ {8}{WR_EN[0]} }),
  155.                         .addr2({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR[2*ABITS-1:ABITS] }),
  156.                         .addr2__U({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR[2*ABITS-1:ABITS] }),
  157.                         .data2(RD_DATA[1]),
  158.                         .out2(WR_DATA[1]),
  159.                         .we2({ {8}{WR_EN[1]} }),
  160.                         .we2__U({ {8}{WR_EN[1]} })
  161.                 );
  162.           end
  163.         endgenerate
  164. endmodule
  165.  
  166. module \$__mem_Wx1_sp_generator (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN);
  167.         parameter ABITS = 4;
  168.         parameter SIZE = 16;
  169.  
  170.         input CLK, WR_DATA, WR_EN;
  171.         input [ABITS-1:0] RD_ADDR, WR_ADDR;
  172.         output RD_DATA;
  173.  
  174.         wire [1023:0] _TECHMAP_DO_ = "proc; clean";
  175.  
  176.         generate
  177.           if (ABITS > `MEM_MAXWIDTH) begin
  178.                 wire high_rd_data, low_rd_data;
  179.                 if (SIZE > 2**(ABITS-1)) begin
  180.                         \$__mem_Wx1_sp_generator #(
  181.                                 .ABITS(ABITS-1),
  182.                                 .SIZE(SIZE - 2**(ABITS-1)),
  183.                         ) part_high (
  184.                                 .CLK(CLK),
  185.                                 .RD_ADDR(RD_ADDR[ABITS-2:0]),
  186.                                 .RD_DATA(high_rd_data),
  187.                                 .WR_ADDR(WR_ADDR[ABITS-2:0]),
  188.                                 .WR_DATA(WR_DATA),
  189.                                 .WR_EN(WR_EN && WR_ADDR[ABITS-1])
  190.                         );
  191.                 end else begin
  192.                         assign high_rd_data = 1'bx;
  193.                 end
  194.                 \$__mem_Wx1_sp_generator #(
  195.                         .ABITS(ABITS-1),
  196.                         .SIZE(SIZE > 2**(ABITS-1) ? 2**(ABITS-1) : SIZE),
  197.                 ) part_low (
  198.                         .CLK(CLK),
  199.                         .RD_ADDR(RD_ADDR[ABITS-2:0]),
  200.                         .RD_DATA(low_rd_data),
  201.                         .WR_ADDR(WR_ADDR[ABITS-2:0]),
  202.                         .WR_DATA(WR_DATA),
  203.                         .WR_EN(WR_EN && !WR_ADDR[ABITS-1])
  204.                 );
  205.                 reg delayed_abit;
  206.                 always @(posedge CLK)
  207.                         delayed_abit <= RD_ADDR[ABITS-1];
  208.                 assign RD_DATA = delayed_abit ? high_rd_data : low_rd_data;
  209.           end else begin
  210.                 single_port_ram _TECHMAP_REPLACE_ (
  211.                         .clk(CLK),
  212.                         .addr({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR }),
  213.                         .addr__U({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR }),
  214.                         .addr__AL({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR }),
  215.                         .addr__AU({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR }),
  216.                         .data(RD_DATA),
  217.                         .out(WR_DATA),
  218.                         .we({ {8}{WR_EN} }),
  219.                         .we__U({ {8}{WR_EN} })
  220.                 );
  221.           end
  222.         endgenerate
  223. endmodule
  224.  
  225. module \$mul (A, B, Y);
  226.         parameter A_SIGNED = 0;
  227.         parameter B_SIGNED = 0;
  228.         parameter A_WIDTH = 1;
  229.         parameter B_WIDTH = 1;
  230.         parameter Y_WIDTH = 1;
  231.  
  232.         input [A_WIDTH-1:0] A;
  233.         input [B_WIDTH-1:0] B;
  234.         output [Y_WIDTH-1:0] Y;
  235.  
  236.         wire [1023:0] _TECHMAP_DO_ = "proc; clean";
  237.  
  238.         parameter _TECHMAP_CONSTMSK_A_ = A_WIDTH'b0;
  239.         parameter _TECHMAP_CONSTMSK_B_ = B_WIDTH'b0;
  240.         parameter _TECHMAP_CONSTVAL_A_ = A_WIDTH'bx;
  241.         parameter _TECHMAP_CONSTVAL_B_ = B_WIDTH'bx;
  242.  
  243.         integer a_width = A_WIDTH;
  244.         integer b_width = B_WIDTH;
  245.         integer tmp;
  246.  
  247.         reg _TECHMAP_FAIL_;
  248.         initial begin
  249.                 _TECHMAP_FAIL_ <= 0;
  250.                
  251.                 if (A_SIGNED || B_SIGNED)
  252.                         _TECHMAP_FAIL_ <= 1;
  253.  
  254.                 //if (A_WIDTH < B_WIDTH)
  255.                 //      _TECHMAP_FAIL_ <= 1;
  256.  
  257.                 //if (A_WIDTH > `DSP_A_MAXWIDTH || B_WIDTH > `DSP_B_MAXWIDTH)
  258.                 //      _TECHMAP_FAIL_ <= 1;
  259.  
  260.                 //if (Y_WIDTH > (`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH))
  261.                 //      _TECHMAP_FAIL_ <= 1;
  262.         end
  263.  
  264.         localparam A_WIDTH_NEW = (_TECHMAP_CONSTMSK_A_ === {{A_WIDTH}{1'b1}} ? $clog2(_TECHMAP_CONSTVAL_A_) : A_WIDTH );
  265.         localparam B_WIDTH_NEW = (_TECHMAP_CONSTMSK_B_ === {{B_WIDTH}{1'b1}} ? $clog2(_TECHMAP_CONSTVAL_B_) : B_WIDTH );
  266.         //localparam Y_WIDTH_NEW = (A_WIDTH_NEW+BWIDTH_NEW-1 < Y_WIDTH ? A_WIDTH_NEW+B_WIDTH_NEW-1 : Y_WIDTH );
  267.  
  268.         generate
  269.                 begin
  270.                         \$__mul_AxB_generator #(
  271.                                 .A_SIGNED(A_SIGNED),
  272.                                 .B_SIGNED(B_SIGNED),
  273.                                 .A_WIDTH(A_WIDTH_NEW),
  274.                                 .B_WIDTH(B_WIDTH_NEW),
  275.                                 .Y_WIDTH(Y_WIDTH)
  276.                         ) mul_slice (
  277.                                 .A(A[A_WIDTH_NEW-1:0]),
  278.                                 .B(B[B_WIDTH_NEW-1:0]),
  279.                                 .Y(Y[Y_WIDTH-1:0])
  280.                         );
  281.                 end
  282.         endgenerate
  283. endmodule
  284.  
  285. module \$__mul_AxB_generator (A, B, Y);
  286.         parameter A_SIGNED = 0;
  287.         parameter B_SIGNED = 0;
  288.         parameter A_WIDTH = 1;
  289.         parameter B_WIDTH = 1;
  290.         parameter Y_WIDTH = 1;
  291.  
  292.         input [A_WIDTH-1:0] A;
  293.         input [B_WIDTH-1:0] B;
  294.         output [Y_WIDTH-1:0] Y;
  295.  
  296.         wire [1023:0] _TECHMAP_DO_ = "proc; clean";
  297.  
  298.         generate
  299.                 if (A_WIDTH > `DSP_A_MAXWIDTH) begin
  300.                         localparam n_floored = A_WIDTH/`DSP_A_MAXWIDTH;
  301.                         localparam n = n_floored + (n_floored*`DSP_A_MAXWIDTH < A_WIDTH ? 1 : 0);
  302.                         wire [Y_WIDTH-1:0] partial [n-1:1];
  303.                         wire [Y_WIDTH-1:0] partial_sum [n-2:0];
  304.  
  305.                         \$__mul_AxB_generator #(
  306.                                 .A_SIGNED(A_SIGNED),
  307.                                 .B_SIGNED(B_SIGNED),
  308.                                 .A_WIDTH(`DSP_A_MAXWIDTH),
  309.                                 .B_WIDTH(B_WIDTH),
  310.                                 .Y_WIDTH(Y_WIDTH)
  311.                         ) mul_slice_first (
  312.                                 .A(A[`DSP_A_MAXWIDTH-1:0]),
  313.                                 .B(B),
  314.                                 .Y(partial_sum[0])
  315.                         );
  316.  
  317.                         genvar i;
  318.                         generate
  319.                                 for (i = 1; i < n-1; i=i+1) begin:slice
  320.                                         \$__mul_AxB_generator #(
  321.                                                 .A_SIGNED(A_SIGNED),
  322.                                                 .B_SIGNED(B_SIGNED),
  323.                                                 .A_WIDTH(`DSP_A_MAXWIDTH),
  324.                                                 .B_WIDTH(B_WIDTH),
  325.                                                 .Y_WIDTH(Y_WIDTH)
  326.                                         ) mul_slice (
  327.                                                 .A(A[(i+1)*`DSP_A_MAXWIDTH-1:i*`DSP_A_MAXWIDTH]),
  328.                                                 .B(B),
  329.                                                 .Y(partial[i])
  330.                                         );
  331.                                         assign partial_sum[i] = partial[i] << i*`DSP_A_MAXWIDTH + partial_sum[i-1];
  332.                                 end
  333.                         endgenerate
  334.  
  335.                         \$__mul_AxB_generator #(
  336.                                 .A_SIGNED(A_SIGNED),
  337.                                 .B_SIGNED(B_SIGNED),
  338.                                 .A_WIDTH(A_WIDTH-(n-1)*`DSP_A_MAXWIDTH),
  339.                                 .B_WIDTH(B_WIDTH),
  340.                                 .Y_WIDTH(Y_WIDTH)
  341.                         ) mul_slice_last (
  342.                                 .A(A[A_WIDTH-1:(n-1)*`DSP_A_MAXWIDTH]),
  343.                                 .B(B),
  344.                                 .Y(partial[n-1])
  345.                         );
  346.                         assign Y = partial[n-1] << (n-1)*`DSP_A_MAXWIDTH + partial_sum[n-2];
  347.                 end
  348.                 else if (B_WIDTH > `DSP_B_MAXWIDTH) begin
  349.                         localparam n_floored = B_WIDTH/`DSP_B_MAXWIDTH;
  350.                         localparam n = n_floored + (n_floored*`DSP_B_MAXWIDTH < B_WIDTH ? 1 : 0);
  351.                         wire [Y_WIDTH-1:0] partial [n-1:1];
  352.                         wire [Y_WIDTH-1:0] partial_sum [n-2:0];
  353.  
  354.                         \$__mul_AxB_generator #(
  355.                                 .A_SIGNED(A_SIGNED),
  356.                                 .B_SIGNED(B_SIGNED),
  357.                                 .A_WIDTH(A_WIDTH),
  358.                                 .B_WIDTH(`DSP_B_MAXWIDTH),
  359.                                 .Y_WIDTH(Y_WIDTH)
  360.                         ) mul_slice_first (
  361.                                 .A(A),
  362.                                 .B(B[`DSP_B_MAXWIDTH-1:0]),
  363.                                 .Y(partial_sum[0])
  364.                         );
  365.  
  366.                         genvar i;
  367.                         generate
  368.                                 for (i = 1; i < n-1; i=i+1) begin:slice
  369.                                         \$__mul_AxB_generator #(
  370.                                                 .A_SIGNED(A_SIGNED),
  371.                                                 .B_SIGNED(B_SIGNED),
  372.                                                 .A_WIDTH(A_WIDTH),
  373.                                                 .B_WIDTH(`DSP_B_MAXWIDTH),
  374.                                                 .Y_WIDTH(Y_WIDTH)
  375.                                         ) mul_slice (
  376.                                                 .A(A),
  377.                                                 .B(B[(i+1)*`DSP_B_MAXWIDTH-1:i*`DSP_B_MAXWIDTH]),
  378.                                                 .Y(partial[i])
  379.                                         );
  380.                                         assign partial_sum[i] = partial[i] << i*`DSP_B_MAXWIDTH + partial_sum[i-1];
  381.                                 end
  382.                         endgenerate
  383.  
  384.                         \$__mul_AxB_generator #(
  385.                                 .A_SIGNED(A_SIGNED),
  386.                                 .B_SIGNED(B_SIGNED),
  387.                                 .A_WIDTH(A_WIDTH),
  388.                                 .B_WIDTH(B_WIDTH-(n-1)*`DSP_B_MAXWIDTH),
  389.                                 .Y_WIDTH(Y_WIDTH)
  390.                         ) mul_slice_last (
  391.                                 .A(A),
  392.                                 .B(B[B_WIDTH-1:(n-1)*`DSP_B_MAXWIDTH]),
  393.                                 .Y(partial[n-1])
  394.                         );
  395.                         assign Y = partial[n-1] << (n-1)*`DSP_B_MAXWIDTH + partial_sum[n-2];
  396.  
  397.                 end
  398.                 else begin
  399.                         if (`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH > Y_WIDTH) begin
  400.                                 wire [`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH-Y_WIDTH-1:0] dummy;
  401.                                 multiply _TECHMAP_REPLACE_ (
  402.                                         .a({ {{`DSP_A_MAXWIDTH-A_WIDTH}{1'bx}}, A }),
  403.                                         .b({ {{`DSP_B_MAXWIDTH-B_WIDTH}{1'bx}}, B }),
  404.                                         .out({ dummy, Y })
  405.                                 );
  406.                         end
  407.                         else
  408.                                 multiply _TECHMAP_REPLACE_ (
  409.                                         .a({ {{`DSP_A_MAXWIDTH-A_WIDTH}{1'bx}}, A }),
  410.                                         .b({ {{`DSP_B_MAXWIDTH-B_WIDTH}{1'bx}}, B }),
  411.                                         .out(Y[`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH-1:0])
  412.                                 );
  413.  
  414.                 end
  415.         endgenerate
  416. endmodule
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top