Advertisement
Guest User

Untitled

a guest
May 9th, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. `timescale 1ns / 1ps
  2.  
  3. module crt(
  4.         input clk,
  5.         input rst,
  6.         input start,
  7.        
  8.         input [7:0] x_in,
  9.        
  10.         output busy,
  11.         output reg [7:0] y_out
  12.     );
  13.    
  14.     // states
  15.    
  16.     localparam idle = 4'b0000;
  17.     localparam next = 4'b0001;
  18.     localparam reset = 4'b0010;
  19.    
  20.     localparam y_double_mul_ready = 4'b0011;
  21.     localparam y_triple_mul_start = 4'b0100;
  22.     localparam y_triple_mul_ready = 4'b0101;
  23.     localparam y_inc_b_mul_start = 4'b0110;
  24.     localparam y_inc_b_mul_ready = 4'b0111;
  25.     localparam b_inc_and_shift = 4'b1000;
  26.     localparam x_b_condition = 4'b1001;
  27.     localparam loop = 4'b1010;
  28.    
  29.     reg [3:0] state, next_state;
  30.  
  31.     reg [7:0] y, b, x;
  32.     reg [7:0] a_mul1, b_mul1;
  33.     reg start_mul1;
  34.     wire [7:0] result_mul1;
  35.     reg reset_mul1;
  36.     wire busy_mul1;
  37.     reg [4:0] s;
  38.     wire [4:0] end_step;
  39.    
  40.     mult mul1(
  41.         .clk_i(clk),
  42.         .rst_i(reset_mul1),
  43.         .a_bi(a_mul1),
  44.         .b_bi(b_mul1),
  45.         .start_i(start_mul1),
  46.         .busy_o(busy_mul1),
  47.         .y_bo(result_mul1)
  48.     );
  49.      
  50.     assign busy = (state != idle);
  51.     assign end_step = (s == 5'd0);
  52.    
  53.     always@ (posedge clk)
  54.         if(rst)begin
  55.            s <= 6;
  56.            y_out <= 0;
  57.            y <= 0;
  58.            state <= idle;
  59.         end else begin
  60.        
  61.             case (state)
  62.                 reset:
  63.                     begin
  64.                        reset_mul1 <= 0;  
  65.                        state <= next;
  66.                     end
  67.                 next:
  68.                     begin
  69.                         state <= next_state;
  70.                     end
  71.                 idle:
  72.                     if(start) begin // starting y * 2 mul process
  73.                         state <= reset;
  74.                         next_state <= y_double_mul_ready;
  75.                         s <= 6;
  76.                         y <= 0;
  77.                         x <= x_in;
  78.                         reset_mul1 <= 1;
  79.                         start_mul1 <= 1;
  80.                         a_mul1 <= 2;
  81.                         b_mul1 <= y;
  82.                     end
  83.                 y_double_mul_ready:  // y = 2 * y
  84.                     if(!busy_mul1) begin
  85.                         state <= y_triple_mul_start;
  86.                         start_mul1 <= 0;
  87.                         y <= result_mul1;  
  88.                     end
  89.                 y_triple_mul_start: // starting y * 3 mul process
  90.                     begin
  91.                         state <= reset;
  92.                         next_state <= y_triple_mul_ready;
  93.                         reset_mul1 <= 1;
  94.                         start_mul1 <= 1;
  95.                         a_mul1 <= y;
  96.                         b_mul1 <= 3;                    
  97.                     end
  98.                 y_triple_mul_ready: // b = y * 3
  99.                     if(!busy_mul1) begin
  100.                         state <= y_inc_b_mul_start;
  101.                         start_mul1 <= 0;
  102.                         b <= result_mul1;
  103.                     end  
  104.                 y_inc_b_mul_start: // starting b*(y+1) or 3*y*(y+1) mul process
  105.                     begin
  106.                         state <= reset;
  107.                         next_state <= y_inc_b_mul_ready;
  108.                         reset_mul1 <= 1;
  109.                         start_mul1 <= 1;
  110.                         a_mul1 <= y+1;
  111.                         b_mul1 <= b;
  112.                     end
  113.                 y_inc_b_mul_ready: // b = 3*y*(y+1)
  114.                     if(!busy_mul1) begin
  115.                         state <= b_inc_and_shift;
  116.                         b <= result_mul1;
  117.                     end
  118.                 b_inc_and_shift: // b = (3*y*(y+1))+1 << s
  119.                     begin
  120.                         state <= x_b_condition;
  121.                         b <= (b+1) << s;
  122.                     end
  123.                 x_b_condition: // checking for x >= b and doing operations according to algorithm
  124.                     if( x >= b ) begin
  125.                         state <= loop;
  126.                         x <= x - b;
  127.                         y <= y + 1;
  128.                     end else begin
  129.                         state <= loop;
  130.                     end
  131.                 loop: // starting again or finishing calculation
  132.                     begin
  133.                         if (end_step) begin // finishing calculation
  134.                             state <= idle;
  135.                             y_out <= y;
  136.                         end else begin // starting again
  137.                             s <= s-3;
  138.                             state <= reset;
  139.                             next_state <= y_double_mul_ready;
  140.                             a_mul1 <= 2; // starting y * 2 mul process again
  141.                             b_mul1 <= y;
  142.                             reset_mul1 <= 1;
  143.                         end    
  144.                     end                
  145.             endcase
  146.         end
  147. endmodule
  148.  
  149.  
  150. //////////////////////////////////////////////
  151.  
  152. `timescale 1ns / 1ps
  153.  
  154. module crt_tb;
  155.  
  156. reg rst;
  157. reg clk;
  158. reg start;
  159. reg [7:0] x_in;
  160. wire busy;
  161. wire [7:0] y_out;
  162.  
  163. crt crt_1(
  164.     .clk(clk),
  165.     .rst(rst),
  166.     .start(start),
  167.     .x_in(x_in),
  168.     .busy(busy),
  169.     .y_out(y_out)
  170. );
  171.  
  172. initial begin
  173.    clk = 0;
  174.    forever #8 clk = !clk;
  175. end
  176.  
  177. task cub_root_test( input [7:0] x,y);
  178. begin
  179.     rst = 1;
  180.     #100
  181.     rst = 0;
  182.     x_in = x;
  183.     start = 1;
  184.     @(posedge busy);
  185.     start = 0;
  186.     @(negedge busy);
  187.     #5
  188.     if (y == y_out) begin
  189.     $display("x = %d, y = %d - test passed", x_in, y_out);
  190.     end else begin
  191.     $display("x = %d, y = %d - test failed. Correct result is: %d", x_in, y_out, y);
  192.     end
  193. end
  194. endtask
  195.  
  196. initial begin
  197.    cub_root_test(1,1);  
  198.    cub_root_test(8,2);  
  199.    cub_root_test(9,2);  
  200.    cub_root_test(10,2);
  201.    cub_root_test(14,2);
  202.    cub_root_test(26,2);  
  203.    cub_root_test(27,3);  
  204.    cub_root_test(64,4);
  205.    cub_root_test(70,4);
  206.    cub_root_test(101,4);
  207.    cub_root_test(125,5);  
  208.    cub_root_test(135,5);
  209.    cub_root_test(216,6);  
  210.    cub_root_test(255,6);  
  211. #1000 $stop;
  212. end
  213.  
  214. endmodule
  215.  
  216. //////////////////////////////////////////////////////////////
  217.  
  218.  
  219. module mult (
  220.     input clk_i,
  221.     input rst_i,
  222.  
  223.     input [7:0] a_bi,
  224.     input [7:0] b_bi,
  225.     input start_i,
  226.  
  227.     output busy_o,
  228.     output reg [15:0] y_bo
  229. );
  230.  
  231.     localparam IDLE = 1'b0;
  232.     localparam WORK = 1'b1;
  233.  
  234.     reg  [3:0]  ctr;
  235.     wire [2:0]  ctr_next, end_step;
  236.     wire [7:0]  part_sum;
  237.     wire [15:0] shifted_part_sum;
  238.     reg [7:0]   a, b;
  239.     reg [15:0]   part_res;
  240.     reg state;
  241.  
  242.     assign part_sum = a & {8{b[ctr]}};
  243.     assign shifted_part_sum = part_sum << ctr;
  244.     assign ctr_next = ctr + 1;
  245.     assign end_step = (ctr == 4'h8);
  246.     assign busy_o = state;
  247.  
  248.     always@(posedge clk_i)
  249.         if(rst_i) begin
  250.            ctr      <= 0;
  251.            part_res <= 0;
  252.            y_bo     <= 0;
  253.  
  254.            state <= IDLE;
  255.         end else begin
  256.  
  257.             case(state)
  258.                 IDLE:
  259.                     if(start_i) begin
  260.                         state  <= WORK;
  261.  
  262.                         a        <= a_bi;
  263.                         b        <= b_bi;
  264.                         ctr      <= 0;
  265.                         part_res <= 0;
  266.                     end
  267.                 WORK:
  268.                     begin
  269.                         if(end_step) begin
  270.                             state  <= IDLE;
  271.                             y_bo   <= part_res;
  272.                         end
  273.  
  274.                         part_res = part_res + shifted_part_sum;
  275.                         ctr <= ctr + 1;
  276.                     end
  277.             endcase
  278.         end
  279.  
  280. endmodule
  281.  
  282. ///////////////////////////////////
  283.  
  284. module mult_tb;
  285. reg clk_i;
  286. reg rst_i;
  287. reg [7:0] a_bi;
  288. reg [7:0] b_bi;
  289. reg start_i;
  290. wire busy_o;
  291. wire [7:0] y_bo;
  292.  
  293. mult mul1 (
  294.         .clk_i(clk_i),
  295.         .rst_i(rst_i),
  296.         .a_bi(a_bi),
  297.         .b_bi(b_bi),
  298.         .start_i(start_i),
  299.         .busy_o(busy_o),
  300.         .y_bo(y_bo)
  301.     );
  302.    
  303. initial begin
  304.    clk_i = 0;
  305.    forever #8 clk_i = !clk_i;
  306. end
  307.    
  308. task mull_test(input reg [7:0] a,b,c);
  309. begin
  310.     rst_i = 1;
  311.     #100
  312.     rst_i = 0;
  313.     a_bi = a;
  314.     b_bi = b;
  315.     start_i = 1;
  316.     @(posedge busy_o);
  317.     start_i = 0;
  318.     @(negedge busy_o);
  319.     #5
  320.     if (c == y_bo) begin
  321.     $display("a = %d, b = %d, c = %d - test passed", a, b, c);
  322.     end else begin
  323.     $display("a = %d, b = %d, c = %d - test failed. Correct c is %d", a, b, y_bo, c);
  324.     end
  325. end
  326. endtask
  327.    
  328. initial begin
  329. mull_test(3,0,0);
  330. mull_test(0,3,0);
  331. mull_test(1,2,2);
  332. mull_test(6,7,42);
  333. #1000 $stop;
  334. end
  335.    
  336. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement