This is the fourth day of my participation in the November Gwen Challenge. Check out the details: The last Gwen Challenge 2021
Writing in the front
- The experiment realizes the addition, subtraction, multiplication, logical operation and comparison of signed numbers without using [+,-, *,>,<] symbols. [Computer Composition and Design] experiment —-PS: Today is the sixth day of installation vivido, almost from scratch, so painful.
- Because the code is too long, the following is only part of the code, I put the whole code in another blog.
1. Experimental tasks
- This experiment needs to realize a CPU arithmetic unit. The simple arithmetic unit consists of three 8-bit registers, R0, R1, R2, and an arithmetic logic unit (ALU), which should support at least addition, subtraction, multiplication, bitwise and, bitwise or, bitwise xOR, and logical non operations.
- The input is controlled by a switch; After each step of operation, the corresponding flag bit (flag bit setting is the same as experiment 4) is represented by LED lamp; The result of the operation is displayed in decimal through a nibble tube. The result of reading data is displayed in decimal through a nibble tube. Control signals such as clock signal and reset signal can be controlled by switch.
- Note: 1. All data involved in this experiment are complement codes. 2. Experimental description The default instruction set given is composed of fixed-length instructions, wherein the opcode of the instruction is variable-length opcode.
2. Experimental description
- The experiment uses eight-bit binary strings (B7b6b5b4b3b2B1B0) to represent instructions, corresponding to eight switches on the development board. The experiment uses four bits of binary complement as input, corresponding to four switches on the development board. Three registers R0, R1 and R2 correspond to binary address codes 00, 01 and 10 respectively.
- Note: The result of the operation is always stored in register R2 by default so it is not explicitly indicated in the instruction. The result of signed multiplication exceeding 8 bits should be interpreted as overflow.
1. Operation instruction format
- The higher bits (b7b6b5b4) are the opcode, the lower bits (b3B2) are the register where the first operand is stored, and the lower bits (b1B0) are the register where the second operand is stored.
- Operation instruction opcode (B7B6B5B4) : operation operation
- 0000 ——-> A + B
- 0001 ——-> A + 1
- 0010 ——-> A – B
- 0011 ——-> A – 1
- 1100 ——-> A * B
- 0100 ——-> Bitwise and
- 0101 ——-> Bitwise or
- 0110 ——-> Bitwise xOR
- 0111 ——-> A > B ?
2, storage instruction format
- The highest two bits (b7b6) are opcodes set to 10, the next highest two bits (b5b4) are address codes written to registers, and the lowest four bits (b3b2b1B0) are the binary complement of data to be written.
3. Read instruction format
- The highest six bits (b7b6b5b4b3B2) are the opcode set 111100, and the lowest two bits (b1B0) are the address code set 10. The instruction is required to read the value of register R2 and display it in decimal through a nibit.
2. Main experimental code and annotations
module adder( input ia, input ib, input cin, output cout, output cur ); assign cur = ia ^ ib ^ cin; / / the current position of the assign cout = ia & cin | ib & cin | ia and ib. // endModule module add_8(input [7:0] a, input [7:0] b, input, output [7:0] s, output o, // overflow, output cout ); wire c0,c1,c2,c3,c4,c5,c6,c7; adder d0(a[0],b[0],cin,c0,s[0]); adder d1(a[1],b[1],c0,c1,s[1]); adder d2(a[2],b[2],c1,c2,s[2]); adder d3(a[3],b[3], c2,c3,s[3]); adder d4(a[4],b[4],c3,c4,s[4]); adder d5(a[5],b[5],c4,c5,s[5]); adder d6(a[6],b[6],c5,c6,s[6]); adder d7(a[7],b[7],c6,c7,s[7]); assign cout = c7; assign o = (a[7] & b[7] & ~s[7]) | (~a[7] & ~b[7] & s[7]); // overflow endModule module add_sub_8(input [7:0] a, input [7:0] b, input cin, input op, output [7:0] res, output overflow, output cout ); add_8 d4(a,{op,op,op,op,op,op,op,op} ^ b,op ^ cin,res,overflow,cout); endmodule module slt( input [7:0] a, input [7:0] b, output result ); wire o, c; wire [7:0] r; add_sub_8 sub(a, b, 0, 1, r, o, c); assign result = o ^ r[7]; endmodule module shift( input [7:0] a, input b, input [1:0]m, output [7:0] out ); // assign out = b == 1'b0? 8'b0000_0000 : ((8'b1111_1111 & a) << m); endmodule module mult( input [3:0] a, input [3:0] b, output [7:0] out ); wire [7:0] abs_a; // absolute value of a wire [7:0] ABS_b; // absolute value of b wire flag; assign flag = a[3] ^ b[3]; // Sign wire [3:0] t1; // Sign wire [3:0] t1; wire [3:0] t2; wire o1,c1,o2,c2,o3,c3,o4,c4,o5,c5,o6,c6; Add_sub_8 m0 (a, 1, 1, t1, o1, c1); // add_sub_8 m1(b,1,0,1, T2, O2,c2); // b - 1 assign abs_a[7:4] = 4'b0000; Assign ABS_B [7:4] = 4'b0000; assign abs_a[3:0] = a[3] == 1'b1 ? ~t1 : a; // Take absolute value to complete Assign ABS_B [3:0] = b[3] == 1'b1? ~t2 : b; wire [7:0] T1; wire [7:0] T2; wire [7:0] T3; wire [7:0] T4; shift h1(abs_a,abs_b[0],2'b00,T1); // Four-digit multiplication converts to four addition operations shift h2(ABS_A, ABS_B [1],2'b01,T2); shift h3(abs_a,abs_b[2],2'b10,T3); shift h4(abs_a,abs_b[3],2'b11,T4); wire [7:0] T5; wire [7:0] T6; wire [7:0] res; wire [7:0] T7; Add_sub_8 m2 (T1, T2, 0, 0, 0, o3, c3); / / T5 = T1 + T2 add_sub_8 m3 (T5, T3, 0, 0, T6, m1, c4); // T6 = T5 + T3 add_sub_8 m4(T6,T4,0,0,res,o5,c5); / / res = T6 + T4 add_sub_8 m5 (~ res, 0, 1, T7 has o6, c6); T7 = ~res + 1 assign out = flag == 1'b1? T7 : res; // Marked by the product symbol, Endmodule module CPU(input read_to_R2, // whether to store the value to R2 INPUT ALu, // control whether to enable the ALU part of the calculation of input CLK, // output reg [7:0] led_id, output reg [6:0] out_LED, // output ZF, CF, // borrow flag bit OF, // overflow flag bit SF, // sign flag bit, same as the highest bit OF F PF // parity flag bit, if F has an odd number OF 1s, PF=1, otherwise 0); reg [7:0] R0; // Address code 00 reg [7:0] R1; // Address code 01 reg [7:0] R2; // Address code 10 reg [7:0] data_to_R2; Wire [7:0] res1, RES2,res3,res4,res5; wire res9; wire OF1,OF2,OF3,OF4; wire CF1,CF2,CF3,CF4; reg of,cf; reg [7:0] A1; reg [7:0] B1; wire [7:0] A; // First source data wire [7:0] B; // Assign A = A1; assign B = B1; Add_sub_8 fun1 (A, B, 0, 0, res1 OF1, CF1); // res1 = A + B add_sub_8fun2 (A,1,0,0,res2,OF2,CF2); // res2 = a-1 add_sub_8 fun3(A,B,0,1,res3,OF3,CF3); // res3 = a-b add_sub_8fun4 (A,1,0,1,res4,OF4,CF4); // res4 = A - 1; mult fun5(A[3:0],B[3:0],res5); // res5 = A * B slt fun9(A,B,res9); A >= B, res9 = 0; A < B, res9 = 1; always@(b) begin if (read_to_R2 == 1'b1) R2 = data_to_R2; If (b[7:6] == 2' b10&&alu == 1' B0) begin If (b[5:4] == 2'b00) begin If (b[3] == 1'b1) R0[7:4] = 4'b1111; R0[7:4] = 4'b0000; else R0[7:4] = 4'b0000; R0[3:0] = b[3:0]; end else if (b[5:4] == 2'b01) begin if (b[3] == 1'b1) R1[7:4] = 4'b1111; else R1[7:4] = 4'b0000; R1[3:0] = b[3:0]; end else if (b[5:4] == 2'b10) begin if (b[3] == 1'b1) begin R2[7:4] = 4'b1111; data_to_R2[7:4] = 4'b1111; end else begin R2[7:4] = 4'b0000; data_to_R2[7:4] = 4'b0000; end R2[3:0] = b[3:0]; data_to_R2 = b[3:0]; end end else if (alu == 1'b1) begin case(b[3:2]) 2'b00: A1 = R0; 2'b01: A1 = R1; 2'b10: A1 = R2; endcase case(b[1:0]) 2'b00: B1 = R0; 2'b01: B1 = R1; 2'b10: B1 = R2; Endcase (b[7:4]) // begin data_to_R2 = res1; of = OF1; cf = CF1; end 4'b0001: begin data_to_R2 = res2; of = OF2; cf = CF2; end 4'b0010: begin data_to_R2 = res3; of = OF3; cf = ~CF3; end 4'b0011: begin data_to_R2 = res4; of = OF4; cf = ~CF4; end 4'b1100: data_to_R2 = res5; 4'b0100: data_to_R2 = A & B; 4'b0101: data_to_R2 = A | B; 4'b0110: data_to_R2 = A ^ B; 4'b0111: data_to_R2 = res9; Endcase end end [7:0] n; assign n = b[7:0] == 8'b1111_0010 ? R2: // read the value of R2 b[7:0] == 8'b1111_0000? R0: // read the value of R0 b[7:0] == 8'b1111_0001? R1: // read the value of R1 b[7:0] == 8'b1111_0011? Data_to_R2: // read the intermediate variable b[7:0] == 8'b1111_0100? A: // Read the second source data b[7:0] == 8'b1111_0101? B: // read the second source data 8'b0000_0000;Copy the code
3, encountered pit
- assignA sequential assignment following a typeThe equal sign on the leftIt must bewireThe type,The right hand sideCan beregType orwireEither type works.
- alwaysInside the blockThe equal sign on the leftIt must beregThe type,The right hand sideCan beregType orwireType.
- The code inside each Alway block is concurrent and executed once when the sensitive list changes, so be careful when using it.