add_minus_multiply
依續輸入4個數字和運算符號,然後計算,輸出結果 example: input: 1234+ output: -0046 input: 1234- output: -022 input: 1234* ouput: 0308 line 49~59: calculate sum, minus, product line 130 ~ 148: distribute sum, minus, product to 4 digit outputunknown
verilog
2 years ago
5.4 kB
1
Indexable
Never
`include "global.v" /* `define STAT_RESET 3'b000 `define STAT_FIRST_INPUT 3'b001 `define STAT_SECOND_INPUT 3'b010 `define STAT_THIRD_INPUT 3'b011 `define STAT_FOURTH_INPUT 3'b100 `define STAT_RESULT_PLUS 3'b101 `define STAT_RESULT_MINUS 3'b110 `define STAT_RESULT_MULTIPLY 3'b111 `define BCD_NUM 4'd10 `define PLUS 4'd11 `define MINUS 4'd12 `define MULTIPLY 4'd13 `define ENTER 4'd14 `define OTHER_INPUT 4'd15 */ module add_minus_multiply( output reg [3:0] out1, // num1, dig2 output reg [3:0] out2, // num1, dig1 output reg [3:0] out3, // num2, dig2 output reg [3:0] out4, // num2, dig1 input [2:0] state, input [3:0] in, input clk, input rst_n ); reg [3:0] in_delay; reg [2 * 4 - 1:0] in_window; // 2 * BCD_BID_WIDTH wire [3:0] in_delay_next; reg [3:0] out1_next; reg [3:0] out2_next; reg [3:0] out3_next; reg [3:0] out4_next; reg [7:0] sum; // 0~198, smaller than 2 ^^ 8 reg [7:0] difference; // -99~99 -> 0~198(plus 99), smaller than 2 ^^ 8 reg [13:0] product; // 0~9801, smaller than 2 ^^ 14 reg [7:0] sum_next; // 0~198, smaller than 2 ^^ 8 reg [7:0] difference_next; // -99~99 -> 0~198(plus 99), smaller than 2 ^^ 8 reg [13:0] product_next; // 0~9801, smaller than 2 ^^ 14 // sum, difference, product combinational always @* begin if (state == `STAT_FOURTH_INPUT) begin sum_next = (10 * out1 + out2) + (10 * out3 + out4); difference_next = (10 * out1 + out2) - (10 * out3 + out4) + 8'd99; product_next = (10 * out1 + out2) * (10 * out3 + out4); end else begin sum_next = sum; difference_next = difference; product = product; end end // sum, difference, product sequential always @(posedge clk or negedge rst_n) begin if (~rst_n) begin sum <= 8'd0; difference <= 8'd0; product <= 14'd0; end else begin sum <= sum_next; difference <= difference_next; product <= product_next; end end // in_window shift register always @(posedge clk or negedge rst_n) begin if (~rst_n) begin in_window = 8'b0; // 2 * BCD_BID_WIDTH end else begin in_window = {in_window[3:0], in}; end end // in_delay_next assign in_delay_next = in_window[7:4]; // in_delay (delay 1 clk pulse) always @(posedge clk or negedge rst_n) begin if (~rst_n) begin in_delay <= 4'd0; end else begin in_delay <= in_delay_next; end end // combinational always @* begin case (state) `STAT_RESET: begin out1_next = 4'd0; out2_next = 4'd0; out3_next = 4'd0; out4_next = 4'd0; end `STAT_FIRST_INPUT: begin out1_next = in_delay; out2_next = out2; out3_next = out3; out4_next = out4; end `STAT_SECOND_INPUT: begin out1_next = out1; out2_next = in_delay; out3_next = out3; out4_next = out4; end `STAT_THIRD_INPUT: begin out1_next = out1; out2_next = out2; out3_next = in_delay; out4_next = out4; end `STAT_FOURTH_INPUT: begin out1_next = out1; out2_next = out2; out3_next = out3; out4_next = in_delay; end `STAT_RESULT_PLUS: begin out1_next = 4'd0; out2_next = sum / 100; out3_next = sum / 10 % 10; out4_next = sum % 10; end `STAT_RESULT_MINUS: begin out1_next = (difference < 8'd99) ? `MINUS : 4'd0; out2_next = 4'd0; out3_next = (difference < 8'd99) ? (8'd99 - difference) / 10 : (difference - 8'd99) / 10 ; out4_next = (difference < 8'd99) ? (8'd99 - difference) % 10 : (difference - 8'd99) % 10 ; end `STAT_RESULT_MULTIPLY: begin out1_next = product / 1000; out2_next = product / 100 % 10; out3_next = product / 10 % 10; out4_next = product % 10; end default: begin out1_next = 4'd0; out2_next = 4'd0; out3_next = 4'd0; out4_next = 4'd0; end endcase end // sequential always @(posedge clk or negedge rst_n) begin if (~rst_n) begin out1 <= 4'd0; out2 <= 4'd0; out3 <= 4'd0; out4 <= 4'd0; end else begin out1 <= out1_next; out2 <= out2_next; out3 <= out3_next; out4 <= out4_next; end end endmodule