рд╡реЗрд░рд┐рд▓реЙрдЧ рдореЗрдВ рдЗрдВрдЯреЗрдЧрд░ рдХреНрдпреВрдм рд░реВрдЯ

рдкрд░рд┐рдЪрдп


рд╣рдордиреЗ рдмрд╛рдЗрдирд░реА рд╕рд░реНрдЪ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреВрд░реНрдгрд╛рдВрдХ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдкреВрд░реНрдгрд╛рдВрдХ рдХреНрдпреВрдм рд░реВрдЯ рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд┐рдВрдереЗрд╕рд╛рдЗрдмрд▓ рд╡реЗрд░рд┐рд▓реЙрдЧ рдХреЛрдб рдмрдирд╛рдпрд╛ рд╣реИред рдЗрд╕ рдХреЛрдб рдХрд╛ рдЪрдХреНрд░рд╡рд╛рдд IV FPGA рдмреЛрд░реНрдб рдкрд░ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдпрд╣рд╛рдВ рдЖрдк рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЪреАрдЬреЗрдВ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИрдВред

рдЬреАрдердм рд▓рд┐рдВрдХ: рдШрдирдореВрд▓

рдШрдирдореВрд▓ рдХреНрдпрд╛ рд╣реИ?


рд╕рдВрдЦреНрдпрд╛ y рдХрд╛ рдШрдирдореВрд▓ рдПрдХ рд╕рдВрдЦреНрдпрд╛ x рд╣реИ рдЬреЛ рдРрд╕рд╛ рд╣реИ

$ $ рдкреНрд░рджрд░реНрд╢рди $ $ x ^ 3 = y $ $ рдкреНрд░рджрд░реНрд╢рди $ $



рдЙрджрд╛рд╣рд░рдг:

$ $ $ $ $ $ $ $ $


рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рд╣рдо рдПрдХ рдкреВрд░реНрдгрд╛рдВрдХ рдХреНрдпреВрдм рд░реВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдЗрд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдкреВрд░реНрдгрд╛рдВрдХ рд╕рдВрдЦреНрдпрд╛ x рдХрд╛ рдШрдирдореВрд▓ рдПрдХ рдФрд░ рдкреВрд░реНрдгрд╛рдВрдХ рд╕рдВрдЦреНрдпрд╛ рд╣реИ рдЬреИрд╕реЗ:

$$ рдкреНрд░рджрд░реНрд╢рди $$ a ^ 3 \ leqslant x, \\ (a + 1) ^ 3 \ geqslant x $$ рдкреНрд░рджрд░реНрд╢рди $$


рдЙрджрд╛рд╣рд░рдг:

$$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 4 $ $ $ $ рдкреНрд░рджрд░реНрд╢рд┐рдд


рдореБрдЦреНрдп рддрд░реНрдХ


рдЫрд╡рд┐

рдЗрдирдкреБрдЯ рдХреЗ рджреМрд░рд╛рди рдПрдХ рдирдВрдмрд░ рдХреЗ рд╕рд╛рде рд╕рднреА рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдореБрдЦреНрдп рдореЙрдбреНрдпреВрд▓ рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред
рдЗрд╕рдХреА 4 рд╕рдВрднрд╛рд╡рд┐рдд рдХреНрд░рд┐рдпрд╛рдПрдВ рд╣реИрдВ:

  • 10 рд╕реЗ рдЧреБрдгрд╛ рдмрдврд╝рд╛рдПрдБ
  • 10 рд╕реЗ рд╡реЗрддрди рд╡реГрджреНрдзрд┐ (рд╡реЗрддрди рд╡реГрджреНрдзрд┐ рд╣рдореЗрд╢рд╛ 1 рд╕реЗ рдХрдо рдирд╣реАрдВ рд╣реИ)
  • рд╕рдВрдЦреНрдпрд╛ рдмрдврд╝рд╛рдПрдВ
  • рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдХрдореА

рдореБрдЦреНрдп рдореЙрдбреНрдпреВрд▓
module cube_root( input inc, input sub, input next, input prev, input enter, input clk, output wire [7:0] leds, output wire [7:0] control ); reg signed [31:0] exit; wire ready; wire [31:0] res; reg zero = 0; // input // reg inc1 = 0; reg next1 = 0; reg prev1 = 0; reg sub1 = 0; reg enter1 = 0; reg [31:0] decimal = 1; ////////// reg [31:0] to_display; display_bcd display( .clk(clk), .value(ready == 0 ? exit : res), .control(control), .leds(leds) ); calculate calc( .clk(clk), .ready_to_calc(~enter), .num(exit), .ready(ready), .res(res) ); always @(posedge clk) begin if (enter == 1) begin if ((inc1 == 1'b0) && (~inc == 1'b1)) begin exit = exit + decimal; end inc1 = ~inc; if ((sub1 == 1'b0) && (~sub == 1'b1)) begin if (exit > 0) begin exit = exit - decimal; end end sub1 = ~sub; if ((next1 == 1'b0) && (~next == 1'b1)) begin decimal = decimal * 10; end next1 = ~next; if ((prev1 == 1'b0) && (~prev == 1'b1)) begin if (decimal >= 1 && decimal <= 9) begin decimal = 1; end else begin decimal = decimal / 10; end end prev1 = ~prev; end else begin if (ready == 1'b1) begin exit = 0; decimal = 1; end end end endmodule 


рдореБрдЦреНрдп рдореЙрдбреНрдпреВрд▓ cube_root рдореЗрдВ рджреЛ рдЕрдиреНрдп рдореЙрдбреНрдпреВрд▓ рднреА рд╣реИрдВ: рдЧрдгрдирд╛ рдФрд░ display_bcd ред рдкрд╣рд▓рд╛ рдореЙрдбреНрдпреВрд▓ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдЧрдгрдирд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЬрдмрдХрд┐ рджреВрд╕рд░рд╛ рдореЙрдбреНрдпреВрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдорд╛рдиреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред

рдЕрдм, рдЖрдЗрдП рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред

рдореЙрдбреНрдпреВрд▓ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ


рдЧрдгрдирд╛ рдореЙрдбреНрдпреВрд▓ рдПрдХ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдЦреЛрдЬ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдФрд░ рдЬрдм рд╕рднреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ рддреЛ рдпрд╣ рддреИрдпрд╛рд░ рдЪрд░ рдХреЛ 1 рдкрд░ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЙрддреНрддрд░ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рд╕реНрдкреНрд▓реЗ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрдд рд╣реИред

рдореЙрдбреНрдпреВрд▓ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ
 module calculate( input clk, input ready_to_calc, input [31:0] num, output reg ready, output [31:0] res ); integer mid; integer start; integer final; integer counter; assign res = mid; always @(posedge clk) begin if (ready_to_calc == 1) begin if (ready == 0) begin mid = (start + final )/2; if ((mid*mid*mid) > num) begin final = mid; end else begin start = mid; end if (counter == 27) begin ready = 1; counter = 0; end else begin counter = counter + 1; end end end else begin final = 465; start = 0; ready = 0; counter = 0; end end endmodule 


рдпрд╣ рдореЙрдбреНрдпреВрд▓ рдареАрдХ 27 рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЛ рдХреНрдпреЛрдВ рдХрд░рддрд╛ рд╣реИ?
- рдЕрдзрд┐рдХрддрдо рдЗрдирдкреБрдЯ рд╕рдВрдЦреНрдпрд╛ 99999999 рд╣реИред рдЗрд╕рд▓рд┐рдП, рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрднрд╡ рд╕рдВрдЦреНрдпрд╛ рд╣реИ $ рдЗрдирд▓рд╛рдЗрди $ \ log_2 99999999 = 26.575424745 \ рд▓рдЧрднрдЧ 27 $ рдЗрдирд▓рд╛рдЗрди $
рдмрд╛рдЗрдирд░реА рд╕рд░реНрдЪ рдХреА рдКрдкрд░реА рд╕реАрдорд╛ 465 рджреНрд╡рд╛рд░рд╛ рдЖрд░рдВрднрд┐рдХ рдХреНрдпреЛрдВ рд╣реИ?
- рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред $ рдЗрдирд▓рд╛рдЗрди $ \ sqrt [3] {99999999} \ рд▓рдЧрднрдЧ 464 $ рдЗрдирд▓рд╛рдЗрди $

рдореЙрдбреНрдпреВрд▓ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ


рдпрд╣ рдореЙрдбреНрдпреВрд▓ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдЗрд╕рдореЗрдВ рдЖрда рдЖрда-рд╕реЗрдЧрдореЗрдВрдЯ рдбрд┐рд╕реНрдкреНрд▓реЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ 16 рдкрд┐рдиреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╣реЗрд░рдлреЗрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЬрд╣рд╛рдВ рдкреНрд░рджрд░реНрд╢рди рдкрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдПрд▓рдИрдбреА рдХреЗ рд▓рд┐рдП 8 рдкрд┐рди "рдкреНрд░рднрд╛рд░реА" рд╣реИрдВ рдФрд░ рдЕрдиреНрдп 8 рдирд┐рдпрдВрддреНрд░рдг рдЦрдВрдб рд╣реИрдВ, рд╡реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЕрдВрдХреЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВред

рдЗрд╕рд▓рд┐рдП, рд╣рдо рдПрдХ рдкреВрд░реНрдгрд╛рдВрдХ рдорд╛рди рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рдо рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рдпрд╣ рдмрд╛рдЗрдирд░реА_to_BCD рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдорд╛рди рдХреЛ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдмрд╛рдЗрдирд░реА рдирдВрдмрд░ рдХреЛ рдбрдмрд▓ рдбрд╛рдмрд▓ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрд╛рдЗрдирд░реА рдХреЛрдбреЗрдб рджрд╢рдорд▓рд╡ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИ ред рдЙрд╕рдХреЗ рдмрд╛рдж, рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдореВрд▓реНрдп рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рдореЙрдбреНрдпреВрд▓ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ
 module display_bcd ( input clk, input [31:0] value, output [7:0] control, output [7:0] leds ); bcd_convert #(32, 8) bcd_convert( .i_Clock(clk), .i_Binary(value_temp), .i_Start(1'b1), .o_BCD(bcd_number), .o_DV(bcd_ready) ); integer delay = 0; integer final_bcd; reg [2:0] ctrl = 0; reg [4:0] digit; wire bcd_ready; wire [31:0] bcd_number; wire [31:0] digits; assign digits = final_bcd; wire [31:0] value_temp; assign value_temp = value; assign control = ~(1 << ctrl); assign leds = ~ (digit == 0 ? 8'b00111111 : (digit == 1 ? 8'b00000110 : (digit == 2 ? 8'b01011011 : (digit == 3 ? 8'b01001111 : (digit == 4 ? 8'b01100110 : (digit == 5 ? 8'b01101101 : (digit == 6 ? 8'b01111101 : (digit == 7 ? 8'b00000111 : (digit == 8 ? 8'b01111111 : (digit == 9 ? 8'b01101111 : 8'b00000000)))))))))); always @(posedge clk) begin if (bcd_ready) final_bcd = bcd_number; case(ctrl) 0: digit = digits[3:0]; 1: digit = digits[31:4] ? digits[7:4] : 10; 2: digit = digits[31:8] ? digits[11:8] : 10; 3: digit = digits[31:12] ? digits[15:12] : 10; 4: digit = digits[31:16] ? digits[19:16] : 10; 5: digit = digits[31:20] ? digits[23:20] : 10; 6: digit = digits[31:24] ? digits[27:24] : 10; 7: digit = digits[31:28] ? digits[31:28] : 10; endcase delay = delay + 1; if (delay == 10000) ctrl = ctrl + 1; end endmodule ))); module display_bcd ( input clk, input [31:0] value, output [7:0] control, output [7:0] leds ); bcd_convert #(32, 8) bcd_convert( .i_Clock(clk), .i_Binary(value_temp), .i_Start(1'b1), .o_BCD(bcd_number), .o_DV(bcd_ready) ); integer delay = 0; integer final_bcd; reg [2:0] ctrl = 0; reg [4:0] digit; wire bcd_ready; wire [31:0] bcd_number; wire [31:0] digits; assign digits = final_bcd; wire [31:0] value_temp; assign value_temp = value; assign control = ~(1 << ctrl); assign leds = ~ (digit == 0 ? 8'b00111111 : (digit == 1 ? 8'b00000110 : (digit == 2 ? 8'b01011011 : (digit == 3 ? 8'b01001111 : (digit == 4 ? 8'b01100110 : (digit == 5 ? 8'b01101101 : (digit == 6 ? 8'b01111101 : (digit == 7 ? 8'b00000111 : (digit == 8 ? 8'b01111111 : (digit == 9 ? 8'b01101111 : 8'b00000000)))))))))); always @(posedge clk) begin if (bcd_ready) final_bcd = bcd_number; case(ctrl) 0: digit = digits[3:0]; 1: digit = digits[31:4] ? digits[7:4] : 10; 2: digit = digits[31:8] ? digits[11:8] : 10; 3: digit = digits[31:12] ? digits[15:12] : 10; 4: digit = digits[31:16] ? digits[19:16] : 10; 5: digit = digits[31:20] ? digits[23:20] : 10; 6: digit = digits[31:24] ? digits[27:24] : 10; 7: digit = digits[31:28] ? digits[31:28] : 10; endcase delay = delay + 1; if (delay == 10000) ctrl = ctrl + 1; end endmodule 


Bcd рдХрдиреНрд╡рд░реНрдЯ
 module bcd_convert #(parameter INPUT_WIDTH, parameter DECIMAL_DIGITS) ( input i_Clock, input [INPUT_WIDTH-1:0] i_Binary, input i_Start, output [DECIMAL_DIGITS*4-1:0] o_BCD, output o_DV ); parameter s_IDLE = 3'b000; parameter s_SHIFT = 3'b001; parameter s_CHECK_SHIFT_INDEX = 3'b010; parameter s_ADD = 3'b011; parameter s_CHECK_DIGIT_INDEX = 3'b100; parameter s_BCD_DONE = 3'b101; reg [2:0] r_SM_Main = s_IDLE; // The vector that contains the output BCD reg [DECIMAL_DIGITS*4-1:0] r_BCD = 0; // The vector that contains the input binary value being shifted. reg [INPUT_WIDTH-1:0] r_Binary = 0; // Keeps track of which Decimal Digit we are indexing reg [DECIMAL_DIGITS-1:0] r_Digit_Index = 0; // Keeps track of which loop iteration we are on. // Number of loops performed = INPUT_WIDTH reg [7:0] r_Loop_Count = 0; wire [3:0] w_BCD_Digit; reg r_DV = 1'b0; always @(posedge i_Clock) begin case (r_SM_Main) // Stay in this state until i_Start comes along s_IDLE : begin r_DV <= 1'b0; if (i_Start == 1'b1) begin r_Binary <= i_Binary; r_SM_Main <= s_SHIFT; r_BCD <= 0; end else r_SM_Main <= s_IDLE; end // Always shift the BCD Vector until we have shifted all bits through // Shift the most significant bit of r_Binary into r_BCD lowest bit. s_SHIFT : begin r_BCD <= r_BCD << 1; r_BCD[0] <= r_Binary[INPUT_WIDTH-1]; r_Binary <= r_Binary << 1; r_SM_Main <= s_CHECK_SHIFT_INDEX; end // Check if we are done with shifting in r_Binary vector s_CHECK_SHIFT_INDEX : begin if (r_Loop_Count == INPUT_WIDTH-1) begin r_Loop_Count <= 0; r_SM_Main <= s_BCD_DONE; end else begin r_Loop_Count <= r_Loop_Count + 1; r_SM_Main <= s_ADD; end end // Break down each BCD Digit individually. Check them one-by-one to // see if they are greater than 4. If they are, increment by 3. // Put the result back into r_BCD Vector. s_ADD : begin if (w_BCD_Digit > 4) begin r_BCD[(r_Digit_Index*4)+:4] <= w_BCD_Digit + 3; end r_SM_Main <= s_CHECK_DIGIT_INDEX; end // Check if we are done incrementing all of the BCD Digits s_CHECK_DIGIT_INDEX : begin if (r_Digit_Index == DECIMAL_DIGITS-1) begin r_Digit_Index <= 0; r_SM_Main <= s_SHIFT; end else begin r_Digit_Index <= r_Digit_Index + 1; r_SM_Main <= s_ADD; end end s_BCD_DONE : begin r_DV <= 1'b1; r_SM_Main <= s_IDLE; end default : r_SM_Main <= s_IDLE; endcase end // always @ (posedge i_Clock) assign w_BCD_Digit = r_BCD[r_Digit_Index*4 +: 4]; assign o_BCD = r_BCD; assign o_DV = r_DV; endmodule // Binary_to_BCD 


рд▓реЗрдЦрдХ: рдЯреНрдпреВрд░рд┐рди рд▓рд┐рдпреЛрдирд┐рдж, рддрд┐рдЦреЛрдиреЛрд╡ рдирд┐рдХрд┐рддрд╛ред

Source: https://habr.com/ru/post/hi431938/


All Articles