February 9, 2009 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ L03-1 Verilog 2 - Design Examples 6.375 Complex Digital Systems Arvind February 9, 2009February 9, 2009 L03-2 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ Verilog Design Examples ! Greatest Common DivisorFebruary 9, 2009 L03-3 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ GCD in C int GCD( int inA, int inB) { int done = 0; int A = inA; int B = inB; while ( !done ) { if ( A < B ) { swap = A; A = B; B = swap; } else if ( B != 0 ) A = A - B; else done = 1; } return A; } What does the RTL implementation need? State Less-Than Comparator Equal Comparator Subtractor iteration inputs output Swap Termination controlFebruary 9, 2009 L03-4 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ Step 1: Design an appropriate port interface idle input_available operand_A operand_B result_data result_taken result_rdy clk resetFebruary 9, 2009 L03-5 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ Step 2: Design a datapath which has the functional units B A = inA; B = inB; while ( !done ) begin if ( A < B ) swap = A; A = B; B = swap; else if (B != 0) A = A - B; else done = 1; End Y = A; zero? lt A subFebruary 9, 2009 L03-6 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ Step 3: Add the control unit to sequence the datapath B A sel A en B sel B en A<B B=0 zero? lt A sub Control unit should be designed to be either busy or waiting for input or waiting for output to be picked up A = inA; B = inB; while ( !done ) begin if ( A < B ) swap = A; A = B; B = swap; else if (B != 0) A = A - B; else done = 1; End Y = A;February 9, 2009 L03-7 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ Datapath module interface module GCDdatapath#( parameter W = 16 ) ( input clk, // Data signals input [W-1:0] operand_A, input [W-1:0] operand_B, output [W-1:0] result_data, // Control signals (ctrl->dpath) input A_en, input B_en, input [1:0] A_sel, input B_sel, // Control signals (dpath->ctrl) output B_zero, output A_lt_B ); B A sel A en B sel B en A < B B = 0 zero? lt A subFebruary 9, 2009 L03-8 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ Connect the modules wire [W-1:0] B; wire [W-1:0] sub_out; wire [W-1:0] A_out; vcMux3#(W) A_mux ( .in0 (operand_A), .in1 (B), .in2 (sub_out), .sel (A_sel), .out (A_out) ); wire [W-1:0] A; vcEDFF_pf#(W) A_pf ( .clk (clk), .en_p (A_en), .d_p (A_out), .q_np (A) ); B A sel A en B sel B en A < B B = 0 zero? lt A subFebruary 9, 2009 L03-9 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ Connect the modules ... wire [W-1:0] B; wire [W-1:0] sub_out; wire [W-1:0] A_out; vcMux3#(W) A_mux ( .in0 (operand_A), .in1 (B), .in2 (sub_out), .sel (A_sel), .out (A_out) ); wire [W-1:0] A; vcEDFF_pf#(W) A_pf ( .clk (clk), .en_p (A_en), .d_p (A_out), .q_np (A) ); wire [W-1:0] B_out; vcMux2#(W) B_mux ( .in0 (operand_B), .in1 (A), .sel (B_sel), .out (B_out) ); vcEDFF_pf#(W) B_pf ( .clk (clk), .en_p (B_en), .d_p (B_out), .q_np (B) ); assign B_zero = (B==0); assign A_lt_B = (A < B); assign sub_out = A - B; assign result_data = A; Continuous assignment combinational logic is fine Using explicit state helps eliminate issues with non-blocking assignmentsFebruary 9, 2009 L03-10 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ Control unit requires a state machine for valid/ready signals WAIT CALC DONE input_availble ( B = 0 ) result_taken Waiting for new input operands Swapping and subtracting Waiting for consumer to take the result resetFebruary 9, 2009 L03-11 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ Implementing the control logic FSM in Verilog localparam WAIT = 2'd0; localparam CALC = 2'd1; localparam DONE = 2'd2; reg [1:0] state_next; wire [1:0] state; always @( posedge clk) begin state <= state_next; end Localparams are not really parameters at all. They are scoped constants.February 9, 2009 L03-12 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ Control signals for the FSM reg [6:0] cs; always @(*) begin //Default control signals A_sel = A_SEL_X; A_en = 1'b0; B_sel = B_SEL_X; B_en = 1'b0; input_available = 1'b0; result_rdy = 1'b0; case ( state ) WAIT : ... CALC : ... DONE : ... endcase end WAIT: begin A_sel = A_SEL_IN; A_en = 1'b1; B_sel = B_SEL_IN; B_en = 1'b1; input_available = 1'b1; end CALC: if ( A_lt_B ) A_sel = A_SEL_B; A_en = 1'b1; B_sel = B_SEL_A; B_en = 1'b1; else if ( !B_zero ) A_sel = A_SEL_SUB; A_en = 1'b1; end DONE: result_rdy = 1'b1;February 9, 2009 L03-13 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ FSM state transitions always @(*) begin // Default is to stay in the same state state_next = state; case ( state ) WAIT : if ( input_available ) state_next = CALC; CALC : if ( B_zero ) state_next = DONE; DONE : if ( result_taken ) state_next = WAIT; endcase end WAIT CALC DONE input_availble ( B = 0 ) result_taken resetFebruary 9, 2009 L03-14 Courtesy of Arvind http://csg.csail.mit.edu/6.375/ RTL test harness requires proper handling of the ready/valid signals B A sel A en B sel B en A < B B = 0 zero? lt A sub Generic Test Source Generic Test
View Full Document