// // Author: lsilvest // Create Date: 10/10/2009 // // // Copyright (c) 2009 Authors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // converts temperature to character address module temp2char ( input clk, input rst_n, input temp_sign, // temperature sign input [6:0] temp, // integer part of temperature input [3:0] temp_frac, // fractional part of temperature input [3:0] addr, // address offset in temp digits/chars displays output reg [4:0] char_addr, // character address in pacer_font8x16 input go, output done ); localparam TEMP_SZ = 7; localparam FRAC_SZ = 14; localparam space = 9'h10; localparam minus = 9'ha; localparam dot = 9'hb; localparam degree = 9'hd; localparam C = 9'he; localparam idl_st = 3'b000, reset_st = 3'b001, run_st = 3'b010, temp_done_st = 3'b011, all_done_st = 3'b100; reg [2:0] state, next_state; wire [3:0] temp_bcd0; wire [3:0] temp_bcd1; wire [3:0] temp_bcd2; wire [3:0] frac_bcd0; wire [3:0] frac_bcd1; wire [3:0] frac_bcd2; wire [3:0] frac_bcd3; wire temp_carry_bit0; wire temp_carry_bit1; wire frac_carry_bit0; wire frac_carry_bit1; wire frac_carry_bit2; wire rst; wire temp_bin_bit; wire temp_stb; reg [2:0] temp_cntr; assign temp_bin_bit = temp_stb & (temp[TEMP_SZ-1 - temp_cntr]); assign temp_stb = state == run_st; wire frac_bin_bit; wire frac_stb; wire [FRAC_SZ:0] frac; reg [3:0] frac_cntr; assign frac = (temp_frac[3] ? 14'd5000 : 14'd0) + (temp_frac[2] ? 14'd2500 : 14'd0) + (temp_frac[1] ? 14'd1250 : 14'd0) + (temp_frac[0] ? 14'd0625 : 14'd0); assign frac_bin_bit = frac_stb & (frac[FRAC_SZ-1 - frac_cntr]); assign frac_stb = state == run_st || state == temp_done_st; bcd_digit temp_d0(.clk(clk),.enable(temp_stb),.rst_n(rst_n),.rst(rst),.bin_bit(temp_bin_bit), .carry_bit(temp_carry_bit0),.bcd(temp_bcd0)); bcd_digit temp_d1(.clk(clk),.enable(temp_stb),.rst_n(rst_n),.rst(rst),.bin_bit(temp_carry_bit0),.carry_bit(temp_carry_bit1),.bcd(temp_bcd1)); bcd_digit temp_d2(.clk(clk),.enable(temp_stb),.rst_n(rst_n),.rst(rst),.bin_bit(temp_carry_bit1), .bcd(temp_bcd2)); bcd_digit frac_d0(.clk(clk),.enable(frac_stb),.rst_n(rst_n),.rst(rst),.bin_bit(frac_bin_bit), .carry_bit(frac_carry_bit0),.bcd(frac_bcd0)); bcd_digit frac_d1(.clk(clk),.enable(frac_stb),.rst_n(rst_n),.rst(rst),.bin_bit(frac_carry_bit0),.carry_bit(frac_carry_bit1),.bcd(frac_bcd1)); bcd_digit frac_d2(.clk(clk),.enable(frac_stb),.rst_n(rst_n),.rst(rst),.bin_bit(frac_carry_bit1),.carry_bit(frac_carry_bit2),.bcd(frac_bcd2)); bcd_digit frac_d3(.clk(clk),.enable(frac_stb),.rst_n(rst_n),.rst(rst),.bin_bit(frac_carry_bit2), .bcd(frac_bcd3)); // generate state change always@(posedge clk or negedge rst_n) begin if (!rst_n) state <= idl_st; else state <= next_state; end always@(*) begin next_state = state; case (state) idl_st: if (go) next_state = reset_st; reset_st: next_state = run_st; run_st: if (temp_cntr == TEMP_SZ-1) next_state = temp_done_st; temp_done_st: if (frac_cntr == FRAC_SZ-1) next_state = all_done_st; all_done_st: next_state = idl_st; endcase end always@(posedge clk or negedge rst_n) begin if (!rst_n) begin temp_cntr <= 3'b0; frac_cntr <= 4'b0; end else if (rst) begin temp_cntr <= 3'b0; frac_cntr <= 4'b0; end else begin if (state == run_st) temp_cntr <= temp_cntr + 5'b1; if (state == run_st || state == temp_done_st) frac_cntr <= frac_cntr + 5'b1; end end // logic to select character font address: always@(*) begin case (addr) 4'd0: char_addr = space; 4'd1: char_addr = temp_sign && temp_bcd2 != 4'b0 ? minus: space; 4'd2: char_addr = temp_sign && temp_bcd2 == 4'b0 && temp_bcd1 != 4'b0 ? minus : temp_bcd2 == 4'b0 ? space : temp_bcd2; 4'd3: char_addr = temp_sign && temp_bcd2 == 4'b0 && temp_bcd1 == 4'b0 ? minus : temp_bcd1 == 4'b0 ? space : temp_bcd1; 4'd4: char_addr = temp_bcd0; 4'd5: char_addr = dot; 4'd6: char_addr = frac_bcd3; 4'd7: char_addr = frac_bcd2; 4'd8: char_addr = space; 4'd9: char_addr = degree; 4'd10: char_addr = C; 4'd11: char_addr = space; 4'd12: char_addr = space; default: char_addr = space; endcase end assign rst = state == reset_st; assign done = state == all_done_st; endmodule