// Verilog HDL for "LIB", "hadd" "_functional" module hadd (clock, A_in, B_in, carry, sum); // Default values for the timing parameters parameter delay_carry = 33, delay_sum = 37, t_hold = 1, t_setup = 31, t_sep = 11, warning_file = 2; // Declaration of data types input clock, A_in, B_in; output carry, sum; reg trig, carry, sum, data_A, data_B, extra_A, extra_B; // Multi-pulse indicators integer current_time, holdtime, sep_time, left_bound, right_bound, time_A, time_B; initial begin // Initialization trig = 0; left_bound = 0; {data_A, data_B} = 0; {carry, sum} = 0; #0 holdtime = (t_hold < 0) ? 0 : t_hold; end // initial always @(posedge A_in) begin // Store the time position of the data (center of the pulse) time_A = $time + 1; // Store the value of the data input data_A = A_in; // Display warning if more than 1 data pulse comes in 1 clock cycle if (extra_A == 'b1) $fdisplay(warning_file, "Extra pulse detected in module %m at input A at %0d ps.\n", time_A); extra_A = 1; // Set after 1 data pulse comes end // always always @(posedge B_in) begin // Store the time position of the data (center of the pulse) time_B = $time + 1; // Store the value of the data input data_B = B_in; // Display warning if more than 1 data pulse comes in 1 clock cycle if (extra_B == 'b1) $fdisplay(warning_file, "Extra pulse detected in module %m at input B at %0d ps.\n", time_B); extra_B = 1; // Set after 1 data pulse comes end // always always @(posedge clock) // Trigger after clock+holdtime trig <= #(holdtime-1) 1; always @(posedge trig) begin current_time = $time+1-(holdtime-1); // Present time of clock // Delay = 0.5 so that clock cycles do not overlap #0.5 trig = 0; // Generate output only if there are input pulses if ((data_A !== 'b0) | (data_B !== 'b0)) begin // Reset to receive data input in a new clock cycle extra_A = 0; extra_B = 0; // Determine the right boundary of the time range in which there is no timing violation right_bound = current_time - t_setup; casex ({(data_A !== 'b0), (data_B !== 'b0), ((time_A >= left_bound) & (time_A <= right_bound)), ((time_B >= left_bound) & (time_B <= right_bound))}) // Two data inputs and no timing violation 4'b1111: begin sep_time = time_A - time_B; sep_time = (sep_time < 0) ? -sep_time : sep_time; // Separation time violation? if (sep_time < t_sep) begin carry <= #(delay_carry - holdtime) 'bx; sum <= #(delay_sum - holdtime) 'bx; $fdisplay(warning_file, "Violation of separation time in module %m.\nInput A at %0d ps, input B at %0d ps.\n", time_A, time_B); end else carry <= #(delay_carry - holdtime) (data_A & data_B); // Reset to receive new data values in a new clock cycle {data_A, data_B} = 0; end // One data input and no timing violation 4'b101x: begin sum <= #(delay_sum - holdtime) data_A; data_A = 0; end // One data input and no timing violation 4'b01x1: begin sum <= #(delay_sum - holdtime) data_B; data_B = 0; end // Two data inputs and there is timing violation 4'b1100: begin carry <= #(delay_carry - holdtime) 'bx; sum <= #(delay_sum - holdtime) 'bx; // Issue a warning if ((time_A > right_bound) & (time_B > right_bound)) $fdisplay(warning_file, "Violation of hold/setup time in module %m. \nInput A at %0d ps, input B at %0d ps, clock at %0d ps.\n", time_A, time_B, current_time); else if (time_A > right_bound) begin $fdisplay(warning_file, "Violation of hold/setup time in module %m. \nInput A at %0d ps, clock at %0d ps.\n", time_A, current_time); data_B = 0; end else if (time_B > right_bound) begin $fdisplay(warning_file, "Violation of hold/setup time in module %m. \nInput B at %0d ps, clock at %0d ps.\n", time_B, current_time); data_A = 0; end // If a warning has been issued before else {data_A, data_B} = 0; end // One data input and there is timing violation 4'b100x: begin sum <= #(delay_sum - holdtime) 'bx; // Issue a warning if (time_A > right_bound) $fdisplay(warning_file, "Violation of hold/setup time in module %m. \nInput A at %0d ps, clock at %0d ps.\n", time_A, current_time); // If a warning has been issued before else data_A = 0; end // One data input and there is timing violation 4'b01x0: begin sum <= #(delay_sum - holdtime) 'bx; // Issue a warning if (time_B > right_bound) $fdisplay(warning_file, "Violation of hold/setup time in module %m. \nInput B at %0d ps, clock at %0d ps.\n", time_B, current_time); // If a warning has been issued before else data_B = 0; end // Two data inputs and there is timing violation 4'b1110: begin carry <= #(delay_carry - holdtime) 'bx; sum <= #(delay_sum - holdtime) 'bx; // Issue a warning if (time_A > right_bound) $fdisplay(warning_file, "Violation of hold/setup time in module %m. \nInput A at %0d ps, clock at %0d ps.\n", time_A, current_time); // If a warning has been issued before else data_A = 0; end // Two data inputs and there is timing violation 4'b1101: begin carry <= #(delay_carry - holdtime) 'bx; sum <= #(delay_sum - holdtime) 'bx; // Issue a warning if (time_B > right_bound) $fdisplay(warning_file, "Violation of hold/setup time in module %m. \nInput B at %0d ps, clock at %0d ps.\n", time_B, current_time); // If a warning has been issued before else data_B = 0; end endcase // Reset the outputs after 2ps carry <= #(delay_carry - holdtime + 2) 0; sum <= #(delay_sum - holdtime + 2) 0; end // if // Determine the left boundary of the time range in which there is no timing violation left_bound = current_time + t_hold; end // always endmodule [ [ [ 'module', 'hadd', '(', [['clock'], ['A_in'], ['B_in'], ['carry'], ['sum']], ')', ';'], [ [ 'parameter', ['delay_carry', '=', '33'], ['delay_sum', '=', '37'], ['t_hold', '=', '1'], ['t_setup', '=', '31'], ['t_sep', '=', '11'], ['warning_file', '=', '2'], ';'], ['input', 'clock', 'A_in', 'B_in', ';'], ['output', 'carry', 'sum', ';'], [ 'reg', ['trig'], ['carry'], ['sum'], ['data_A'], ['data_B'], ['extra_A'], ['extra_B'], ';'], [ 'integer', ['current_time'], ['holdtime'], ['sep_time'], ['left_bound'], ['right_bound'], ['time_A'], ['time_B'], ';'], [ 'initial', [ 'begin', [ [[['trig'], '=', '0'], ';'], [[['left_bound'], '=', '0'], ';'], [[['{', ['data_A'], ['data_B'], '}'], '=', '0'], ';'], [[['{', ['carry'], ['sum'], '}'], '=', '0'], ';'], [ ['#', '0'], [ [ ['holdtime'], '=', '(', [['t_hold'], '<', '0'], ')', '?', '0', ':', ['t_hold']], ';']]], 'end']], [ 'always', ['@', '(', ['posedge', ['A_in']], ')'], [ 'begin', [ [[['time_A'], '=', ['$time'], '+', '1'], ';'], [[['data_A'], '=', ['A_in']], ';'], [ 'if', ['(', ['extra_A'], '==', "'b 1", ')'], [ '$fdisplay', '(', ['warning_file'], '"Extra pulse detected in module %m at input A at %0d ps.\\n"', ['time_A'], ')', ';']], [[['extra_A'], '=', '1'], ';']], 'end']], [ 'always', ['@', '(', ['posedge', ['B_in']], ')'], [ 'begin', [ [[['time_B'], '=', ['$time'], '+', '1'], ';'], [[['data_B'], '=', ['B_in']], ';'], [ 'if', ['(', ['extra_B'], '==', "'b 1", ')'], [ '$fdisplay', '(', ['warning_file'], '"Extra pulse detected in module %m at input B at %0d ps.\\n"', ['time_B'], ')', ';']], [[['extra_B'], '=', '1'], ';']], 'end']], [ 'always', ['@', '(', ['posedge', ['clock']], ')'], [ [['trig'], '<=', ['#', '(', [['holdtime'], '-', '1'], ')'], '1'], ';']], [ 'always', ['@', '(', ['posedge', ['trig']], ')'], [ 'begin', [ [ [ ['current_time'], '=', ['$time'], '+', '1', '-', '(', [['holdtime'], '-', '1'], ')'], ';'], [['#', '0.5'], [[['trig'], '=', '0'], ';']], [ 'if', [ '(', '(', [['data_A'], '!==', "'b 0"], ')', '|', '(', [['data_B'], '!==', "'b 0"], ')', ')'], [ 'begin', [ [[['extra_A'], '=', '0'], ';'], [[['extra_B'], '=', '0'], ';'], [ [['right_bound'], '=', ['current_time'], '-', ['t_setup']], ';'], [ 'casex', '(', [ '{', '(', [['data_A'], '!==', "'b 0"], ')', '(', [['data_B'], '!==', "'b 0"], ')', '(', [ '(', [['time_A'], '>=', ['left_bound']], ')', '&', '(', [['time_A'], '<=', ['right_bound']], ')'], ')', '(', [ '(', [['time_B'], '>=', ['left_bound']], ')', '&', '(', [['time_B'], '<=', ['right_bound']], ')'], ')', '}'], ')', "4 'b 1111", ':', [ 'begin', [ [[['sep_time'], '=', ['time_A'], '-', ['time_B']], ';'], [ [ ['sep_time'], '=', '(', [['sep_time'], '<', '0'], ')', '?', '-', ['sep_time'], ':', ['sep_time']], ';'], [ 'if', ['(', ['sep_time'], '<', ['t_sep'], ')'], [ 'begin', [ [ [ ['carry'], '<=', [ '#', '(', [['delay_carry'], '-', ['holdtime']], ')'], "'b x"], ';'], [ [ ['sum'], '<=', [ '#', '(', [['delay_sum'], '-', ['holdtime']], ')'], "'b x"], ';'], [ '$fdisplay', '(', ['warning_file'], '"Violation of separation time in module ' '%m.\\nInput A at %0d ps, input B at %0d ' 'ps.\\n"', ['time_A'], ['time_B'], ')', ';']], 'end'], 'else', [ [ ['carry'], '<=', [ '#', '(', [['delay_carry'], '-', ['holdtime']], ')'], '(', [['data_A'], '&', ['data_B']], ')'], ';']], [[['{', ['data_A'], ['data_B'], '}'], '=', '0'], ';']], 'end'], "4 'b 101x", ':', [ 'begin', [ [ [ ['sum'], '<=', ['#', '(', [['delay_sum'], '-', ['holdtime']], ')'], ['data_A']], ';'], [[['data_A'], '=', '0'], ';']], 'end'], "4 'b 01x1", ':', [ 'begin', [ [ [ ['sum'], '<=', ['#', '(', [['delay_sum'], '-', ['holdtime']], ')'], ['data_B']], ';'], [[['data_B'], '=', '0'], ';']], 'end'], "4 'b 1100", ':', [ 'begin', [ [ [ ['carry'], '<=', [ '#', '(', [['delay_carry'], '-', ['holdtime']], ')'], "'b x"], ';'], [ [ ['sum'], '<=', ['#', '(', [['delay_sum'], '-', ['holdtime']], ')'], "'b x"], ';'], [ 'if', [ '(', '(', [['time_A'], '>', ['right_bound']], ')', '&', '(', [['time_B'], '>', ['right_bound']], ')', ')'], [ '$fdisplay', '(', ['warning_file'], '"Violation of hold/setup time in module %m. ' '\\nInput A at %0d ps, input B at %0d ps, clock at ' '%0d ps.\\n"', ['time_A'], ['time_B'], ['current_time'], ')', ';'], 'else', [ 'if', ['(', ['time_A'], '>', ['right_bound'], ')'], [ 'begin', [ [ '$fdisplay', '(', ['warning_file'], '"Violation of hold/setup time in module %m. ' '\\nInput A at %0d ps, clock at %0d ps.\\n"', ['time_A'], ['current_time'], ')', ';'], [[['data_B'], '=', '0'], ';']], 'end'], 'else', [ 'if', ['(', ['time_B'], '>', ['right_bound'], ')'], [ 'begin', [ [ '$fdisplay', '(', ['warning_file'], '"Violation of hold/setup time in module ' '%m. \\nInput B at %0d ps, clock at %0d ' 'ps.\\n"', ['time_B'], ['current_time'], ')', ';'], [[['data_A'], '=', '0'], ';']], 'end'], 'else', [ [['{', ['data_A'], ['data_B'], '}'], '=', '0'], ';']]]]], 'end'], "4 'b 100x", ':', [ 'begin', [ [ [ ['sum'], '<=', ['#', '(', [['delay_sum'], '-', ['holdtime']], ')'], "'b x"], ';'], [ 'if', ['(', ['time_A'], '>', ['right_bound'], ')'], [ '$fdisplay', '(', ['warning_file'], '"Violation of hold/setup time in module %m. ' '\\nInput A at %0d ps, clock at %0d ps.\\n"', ['time_A'], ['current_time'], ')', ';'], 'else', [[['data_A'], '=', '0'], ';']]], 'end'], "4 'b 01x0", ':', [ 'begin', [ [ [ ['sum'], '<=', ['#', '(', [['delay_sum'], '-', ['holdtime']], ')'], "'b x"], ';'], [ 'if', ['(', ['time_B'], '>', ['right_bound'], ')'], [ '$fdisplay', '(', ['warning_file'], '"Violation of hold/setup time in module %m. ' '\\nInput B at %0d ps, clock at %0d ps.\\n"', ['time_B'], ['current_time'], ')', ';'], 'else', [[['data_B'], '=', '0'], ';']]], 'end'], "4 'b 1110", ':', [ 'begin', [ [ [ ['carry'], '<=', [ '#', '(', [['delay_carry'], '-', ['holdtime']], ')'], "'b x"], ';'], [ [ ['sum'], '<=', ['#', '(', [['delay_sum'], '-', ['holdtime']], ')'], "'b x"], ';'], [ 'if', ['(', ['time_A'], '>', ['right_bound'], ')'], [ '$fdisplay', '(', ['warning_file'], '"Violation of hold/setup time in module %m. ' '\\nInput A at %0d ps, clock at %0d ps.\\n"', ['time_A'], ['current_time'], ')', ';'], 'else', [[['data_A'], '=', '0'], ';']]], 'end'], "4 'b 1101", ':', [ 'begin', [ [ [ ['carry'], '<=', [ '#', '(', [['delay_carry'], '-', ['holdtime']], ')'], "'b x"], ';'], [ [ ['sum'], '<=', ['#', '(', [['delay_sum'], '-', ['holdtime']], ')'], "'b x"], ';'], [ 'if', ['(', ['time_B'], '>', ['right_bound'], ')'], [ '$fdisplay', '(', ['warning_file'], '"Violation of hold/setup time in module %m. ' '\\nInput B at %0d ps, clock at %0d ps.\\n"', ['time_B'], ['current_time'], ')', ';'], 'else', [[['data_B'], '=', '0'], ';']]], 'end'], 'endcase'], [ [ ['carry'], '<=', [ '#', '(', [['delay_carry'], '-', ['holdtime'], '+', '2'], ')'], '0'], ';'], [ [ ['sum'], '<=', [ '#', '(', [['delay_sum'], '-', ['holdtime'], '+', '2'], ')'], '0'], ';']], 'end']], [[['left_bound'], '=', ['current_time'], '+', ['t_hold']], ';']], 'end']]], 'endmodule']]