/// Code for LSU EE 4702 Spring 2001 /// Calculator Example /// Changes for Synthesis `define crange 7:0 module calc(display_val,beep,key_code,reset,clk); input [5:0] key_code; input reset, clk; output display_val, beep; `include "calc_keys.v" parameter kty_digit = 6'd30; parameter kty_arith = 6'd31; parameter kty_any = 6'bx; reg [2:0] state, next_state; parameter st_0N = 3'd0; parameter st_0P = 3'd1; parameter st_0C = 3'd2; parameter st_1N = 3'd3; parameter st_1P = 3'd4; parameter st_xx = 3'bxxx; parameter buffer_max = 'h7fffffff; reg [31:0] buffer, acc; reg [5:0] pending_op, key_type; wire [`crange] display_val = buffer; task add_digit; begin if( buffer < buffer_max ) buffer = buffer * 10 + key_code - key_0; end endtask // add_digit function [`crange] do_op; input dummy; begin case( pending_op ) key_plus : do_op = acc + buffer; key_minus : do_op = acc - buffer; key_times : do_op = acc * buffer; // key_divide : do_op = buffer ? acc / buffer : 0; key_divide : do_op = acc - buffer; default : begin // exemplar translate_off $display("Error in behavioral description."); $stop; // exemplar translate_on do_op = 0; // Pacify compiler. end endcase // case( pending_op ) end endfunction // do_op task fatal; input [319:0] message; begin // exemplar translate_off $display("Error in behavioral description: %s",message); $display("Execution stopping."); $stop; // exemplar translate_on end endtask // fatal reg [5:0] beep_time; reg beep_ack, beep_req; reg beep; // assign beep = | beep_time; // always #1 if( beep_time ) beep_time = beep_time - 1; always @( negedge clk ) if( reset ) begin beep_ack = 0; beep_time = 0; end else if( beep_ack ^ beep_req ) begin beep_ack = !beep_ack; beep_time = 20; beep = 1; end else if( beep_time ) beep_time = beep_time - 1; else beep = 0; reg nl; // always @( key_code ) if( key_code != key_none ) begin always @( posedge clk ) if( reset ) begin beep_req = 0; nl = 0; state = st_0N; buffer = 0; acc = 0; pending_op = 0; end else if( key_code == key_none ) nl = 1; else if( nl ) begin nl = 0; case( key_code ) key_0,key_1,key_2,key_3,key_4,key_5,key_6,key_7,key_8,key_9: key_type = kty_digit; key_plus,key_minus,key_times,key_divide: key_type = kty_arith; default: key_type = key_code; endcase // case( key_code ) casex( {state,key_type} ) {st_xx,key_clear}: begin acc = 0; buffer = 0; next_state = st_0N; end {st_0N,kty_digit}: begin add_digit; next_state = st_0P; end {st_0P,kty_digit}: begin add_digit; next_state = state; end {st_0P,kty_arith}: begin pending_op = key_code; acc = buffer; buffer = 0; next_state = st_1N; end {st_0C,kty_digit}: begin buffer = 0; add_digit; next_state = st_0P; end {st_0C,kty_arith}: begin pending_op = key_code; acc = buffer; buffer = 0; next_state = st_1N; end {st_1N,kty_digit}: begin add_digit; next_state = st_1P; end {st_1P,kty_digit}: begin add_digit; next_state = state; end {st_1P,key_equal}: begin buffer = do_op(0); next_state = st_0C; end {st_1P,kty_arith}: begin acc = do_op(0); pending_op = key_code; buffer = 0; next_state = st_1N; end {st_0N,kty_any}, {st_0C,kty_any}, {st_0P,kty_any}, {st_1N,kty_any}, {st_1P,kty_any}: begin beep_req = !beep_req; next_state = state; end default: begin // exemplar translate_off $display("Behavioral code error, unexpected state."); $display("Stopping."); // exemplar translate_on end endcase state = next_state; end // if ( key_code != key_none ) endmodule // calc // exemplar translate_off module demo_calc(); wire [`crange] display; reg [5:0] key; reg clk, reset; calc c1(display,beep,key,reset,clk); `include "calc_keys.v" task command; input [799:0] cmd; integer initialized; integer c; reg [5:0] to_key [0:255]; begin if( initialized === 'bx ) begin for( c = 0; c < 256; c = c + 1 ) to_key[c] = key_never; for( c = 0; c < 10; c = c + 1 ) to_key[ "0" + c ] = key_0 + c; to_key["+"] = key_plus; to_key["-"] = key_minus; to_key["/"] = key_divide; to_key["*"] = key_times; to_key["="] = key_equal; to_key["c"] = key_clear; to_key[" "] = key_none; to_key[0] = key_none; initialized = 1; end // if ( initialized === 'bx ) while( cmd ) begin:COMMAND_LOOP reg [7:0] c; c = cmd[799:792]; @( posedge clk ) @( negedge clk ) key = to_key[ c ]; if( key == key_never ) begin $display("Demo error: illegal key in command, %s (%d)",c,c); $stop; end // #1; @( posedge clk ) @( negedge clk ) if( key != key_none ) $display("Key %s Display %d",c,display); @( posedge clk ) @( negedge clk ) key = key_none; // #1; cmd = cmd << 8; end // block: COMMAND_LOOP end endtask // command always @( posedge beep ) $display("Beep starting."); always @( negedge beep ) $display("Beep finished."); always #1 clk = ~clk; initial begin clk = 0; reset = 0; #2; reset = 1; #2; reset = 0; #2; command("c 5 c 12 + 34 = "); command(" 1 + 2 + 3 ++ 4 = - 10 = "); $stop; end endmodule // demo_calc // exemplar translate_on