/// Code for LSU EE 4702 Spring 2001 /// Calculator Example // Calculator Precision `define crange 7:0 module calc(display_val,beep,key_code); input [5:0] key_code; output display_val; output 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 [`crange] 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; endcase // case( pending_op ) end endfunction // do_op task fatal; input [319:0] message; begin $display("Error in behavioral description: %s",message); $display("Execution stopping."); $stop; end endtask // fatal reg [5:0] beep_time; assign beep = | beep_time; always #1 if( beep_time ) beep_time = beep_time - 1; task do_beep; $display("Beeeeeep!!! %d",state); endtask // do_beep always @( key_code ) if( key_code != key_none ) begin 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_time = 10; next_state = state; end default: begin $display("Behavioral code error, unexpected state."); $display("Stopping."); end endcase // casex( {state,key_type} ) state <= next_state; end // if ( key_code != key_none ) endmodule // calc module demo_calc(); wire [`crange] display; reg [5:0] key; wire beep; calc c1(display,beep,key); `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]; key = to_key[ c ]; if( key == key_never ) begin $display("Demo error: illegal key in command, %s (%d)",c,c); $stop; end #1; if( key != key_none ) $display("Key %s Display %d",c,display); 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."); initial begin command("c 5 c 12 + 34 = "); command(" 1 + 2 + 3 ++ 4 = - 10 = "); $stop; end endmodule // demo_calc