diff --git a/.gitignore b/.gitignore index d8e2b01..6ad7eb7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -**/*.bin \ No newline at end of file +**/*.bin +**/machine_code.txt \ No newline at end of file diff --git a/RTL/Ctrl.sv b/RTL/Ctrl.sv index 79145c3..838e80f 100644 --- a/RTL/Ctrl.sv +++ b/RTL/Ctrl.sv @@ -11,12 +11,13 @@ module Ctrl #( input logic [8:0] Instruction, input logic [W-1:0] ALU_Out, input logic [W-1:0] RegOutA, RegOutB, // select from register inputs or immediate inputs - input logic [T-1:0] ProgCtr_p4, + input logic [T-1:0] ProgCtr_p1, input logic [W-1:0] mem_out, output op_mne ALU_OP, // control ALU operation output logic [W-1:0] ALU_A, ALU_B, output logic RegWrite, Done_in, - output logic [3:0] RaddrA, RaddrB, Waddr, RegInput, + output logic [3:0] RaddrA, RaddrB, Waddr, + output logic [W-1:0] RegInput, output logic BranchEZ, BranchNZ, BranchAlways, output logic write_mem ); @@ -50,90 +51,90 @@ module Ctrl #( BranchAlways = 'b0; write_mem = 'b0; casez(Instruction) - 'b1_xxxx_xxxx: begin // LDI + 'b1_????_????: begin // LDI ALU_A = I_Immediate; end - 'b0_0000_xxxx: begin // PUT + 'b0_0000_????: begin // PUT Waddr = A_operand; end - 'b0_0001_xxxx: begin // GET + 'b0_0001_????: begin // GET RaddrA = A_operand; end - 'b0_0010_0xxx: begin // LDW + 'b0_0010_0???: begin // LDW RaddrA = S_operand; RegInput = mem_out; end - 'b0_0010_1xxx: begin // STW + 'b0_0010_1???: begin // STW RaddrA = S_operand; RegWrite = 'b0; write_mem = 'b1; end - 'b0_0011_0xxx: begin // NXT - if(S_operand == 'd8 || S_operand == 'd9 || S_operand == 'd10) ALU_OP = INC; - else if (S_operand == 'd11 || S_operand == 'd12 || S_operand == 'd13) ALU_OP = DEC; + 'b0_0011_0???: begin // N?T + if(S_operand == 'd8 || S_operand == 'd9 || S_operand == 'd10) ALU_OP = DEC; + else if (S_operand == 'd11 || S_operand == 'd12 || S_operand == 'd13) ALU_OP = INC; else ALU_OP = NOP; RaddrA = S_operand; Waddr = S_operand; end - 'b0_0011_1xxx: begin //CLB + 'b0_0011_1???: begin //CLB ALU_OP = CLB; RaddrA = G_operand; Waddr = G_operand; end - 'b0_0100_xxxx: begin // ADD + 'b0_0100_????: begin // ADD ALU_OP = ADD; RaddrB = A_operand; end - 'b0_0101_xxxx: begin // SUB + 'b0_0101_????: begin // SUB ALU_OP = SUB; RaddrB = A_operand; end - 'b0_0110_xxxx: begin // ORR + 'b0_0110_????: begin // ORR ALU_OP = ORR; RaddrB = A_operand; end - 'b0_0111_xxxx: begin // AND + 'b0_0111_????: begin // AND ALU_OP = AND; RaddrB = A_operand; end - 'b0_1000_0xxx: begin // LSH + 'b0_1000_0???: begin // LSH ALU_OP = LSH; ALU_A = T_Immediate; end - 'b0_1000_1xxx: begin // PTY + 'b0_1000_1???: begin // PTY ALU_OP = RXOR_7; RaddrA = G_operand; end - 'b0_1001_xxxx: begin // CHK + 'b0_1001_????: begin // CHK ALU_OP = RXOR_8; RaddrA = A_operand; end - 'b0_1010_xxxx: begin // XOR + 'b0_1010_????: begin // XOR ALU_OP = XOR; RaddrB = A_operand; end - 'b0_1011_xxxx: begin // DNE + 'b0_1011_????: begin // DNE Done_in = 'b1; end - 'b0_1110_0xxx: begin // JNZ + 'b0_1110_0???: begin // JNZ RegWrite = 'b0; RaddrA = G_operand; BranchNZ = 'b1; end - 'b0_1110_1xxx: begin // JEZ + 'b0_1110_1???: begin // JEZ RegWrite = 'b0; RaddrA = G_operand; BranchEZ = 'b1; end - 'b0_1111_0xxx: begin // JMP + 'b0_1111_0???: begin // JMP RegWrite = 'b0; RaddrA = G_operand; BranchAlways = 'b1; end - 'b0_1111_1xxx: begin // JAL + 'b0_1111_1???: begin // JAL RaddrA = G_operand; Waddr = 'd14; // write to link register specifically - RegInput = ProgCtr_p4; // write the value pc+4 + RegInput = ProgCtr_p1; // write the value pc+4 BranchAlways = 'b1; end endcase diff --git a/RTL/InstFetch.sv b/RTL/InstFetch.sv index 581f36d..9b197fa 100644 --- a/RTL/InstFetch.sv +++ b/RTL/InstFetch.sv @@ -8,18 +8,21 @@ module InstFetch #(parameter T=10, parameter W=8)( // T is PC address size, W input logic Done, // Done flag to indicate if the PC should increment at all input logic [W-1:0] Target, // jump target pointer output logic [T-1:0] ProgCtr, - output logic [T-1:0] ProgCtr_p4 // value of pc+4 for use in JAL instruction itself + output logic [T-1:0] ProgCtr_p1 // value of pc+1 for use in JAL instruction itself ); logic [T-1:0] PC; always_ff @(posedge Clk) begin if(Reset) PC <= 0; // if reset, set PC to 0 - else if (BranchAlways) PC <= Target; // if unconditional branch, assign PC to target - else if (BranchEZ && Zero) PC <= Target; // if branch on zero and zero is true, then assign PC to target - else if (BranchNZ && !Zero) PC <= Target; // if branch on non zero and zero is false, then assign PC to parget + else if (BranchAlways) PC[W-1:0] <= Target; // if unconditional branch, assign PC to target + else if (BranchEZ && Zero) PC[W-1:0] <= Target; // if branch on zero and zero is true, then assign PC to target + else if (BranchNZ && !Zero) PC[W-1:0] <= Target; // if branch on non zero and zero is false, then assign PC to parget else if (!Done) PC <= PC + 'b1; // if not a branch but CPU is not done, then else PC <= PC; end + assign ProgCtr = PC; + assign ProgCtr_p1 = ProgCtr + 1; + endmodule \ No newline at end of file diff --git a/RTL/InstROM.sv b/RTL/InstROM.sv index d0a54d3..0a9285b 100644 --- a/RTL/InstROM.sv +++ b/RTL/InstROM.sv @@ -10,7 +10,7 @@ // // A = program counter width // W = machine code width -- do not change for CSE141L -module InstROM #(parameter A=12, W=9) ( +module InstROM #(parameter A=10, W=9) ( input [A-1:0] InstAddress, output logic[W-1:0] InstOut); diff --git a/RTL/program1_tb1.sv b/RTL/program1_tb1.sv index b9c2262..2992f54 100644 --- a/RTL/program1_tb1.sv +++ b/RTL/program1_tb1.sv @@ -1,39 +1,39 @@ // program1_tb // testbench for programmable message encryption (Program #1) -// CSE141L -// runs program 1 (encrypt a message) -module encrypt_tb () ; -// DUT interface -- four one-bit wires, three to DUT, one from +// CSE141L +// runs program 1 (encrypt a message) +module program1_tb () ; +// DUT interface -- four one-bit wires, three to DUT, one from bit clk , // advances simulation step-by-step - init = 1'b1 , // init (reset) command to DUT + init = 1'b1 , // init (reset) command to DUT start = 1'b1 ; // request (start program) command to DUT wire done ; // acknowledge (program done) flag returned by DUT -// test bench parameters - logic[7:0] pre_length ; // number of space char. before message itself, sent to data_mem[61] +// test bench parameters + logic[7:0] pre_length ; // number of space char. before message itself, sent to data_mem[61] logic[7:0] message1[54] , // original raw message, in binary, up to 54 characters in length msg_padded1[64], // original message, plus pre- and post-padding w/ ASCII spaces msg_crypto1[64]; // encrypted message returned by DUT logic[7:0] lfsr_ptrn , // choses one of 9 maximal length 7-tap shift reg. patterns - LFSR_ptrn[9] , // the 9 candidate maximal-length 7-bit LFSR tap ptrns themselves + LFSR_ptrn[9] , // the 9 candidate maximal-length 7-bit LFSR tap ptrns themselves lfsr1[64] , // states of program 1 encrypting LFSR LFSR_init ; // one of 127 possible NONZERO starting states for encrypting LFSR - int score ; // count of correctly encyrpted characters + int score ; // count of correctly encyrpted characters // our original American Standard Code for Information Interchange message follows -// note in practice your design should be able to handle ANY ASCII string that is -// restricted to characters between space (0x20) and script f (0x9f) and shorter than +// note in practice your design should be able to handle ANY ASCII string that is +// restricted to characters between space (0x20) and script f (0x9f) and shorter than // 55 characters in length string str1 = "Mr. Watson, come here. I want to see you."; // sample program 1 input // string str1 = " Knowledge comes, but wisdom lingers. "; // alternative inputs // string str1 = " 01234546789abcdefghijklmnopqrstuvwxyz. "; // (make up your own, // string str1 = " f A joke is a very serious thing."; // as well) // string str1 = " Ajoke "; // -// string str1 = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"; +// string str1 = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"; // string str1 = " Knowledge comes, but wisdom lingers. "; // // displayed encrypted string will go here: string str_enc1[64]; // program 1 desired output will go here - int strlen; // length of incoming message string itself, before padding - logic[3:0] pt_no; // select LFSR pattern, index value 0 through 8 + int strlen; // length of incoming message string itself, before padding + logic[3:0] pt_no; // select LFSR pattern, index value 0 through 8 int file_no; // output file tag (set to 1 for write to console/transcript) // the 9 possible 7-tap maximal-length feedback tap patterns from which to choose assign LFSR_ptrn[0] = 8'h60; // (0)110_0000 @@ -43,107 +43,107 @@ module encrypt_tb () ; assign LFSR_ptrn[4] = 8'h6A; assign LFSR_ptrn[5] = 8'h69; assign LFSR_ptrn[6] = 8'h5C; - assign LFSR_ptrn[7] = 8'h7E; // (0)111_1110 - assign LFSR_ptrn[8] = 8'h7B; - always_comb begin - pt_no = 0;//$random; // or select a specific pattern ([0] and [1] are simplest to debug - if(pt_no>8) pt_no[3] = 0; // restrict pt_no to 0 through 8 + assign LFSR_ptrn[7] = 8'h7E; // (0)111_1110 + assign LFSR_ptrn[8] = 8'h7B; + always_comb begin + pt_no = 8;//$random; // or select a specific pattern ([0] and [1] are simplest to debug + if(pt_no>8) pt_no[3] = 0; // restrict pt_no to 0 through 8 lfsr_ptrn = LFSR_ptrn[pt_no]; // look up and engage the selected pattern; to data_mem[62] end // now select a starting LFSR state -- any nonzero value will do - always_comb begin + always_comb begin LFSR_init = 'b1;//$random>>2; // or set a specific value, such as 7'b1, for easier debug - if(!LFSR_init) LFSR_init = 7'b1; // prevents illegal starting state = 7'b0; - end + if(!LFSR_init) LFSR_init = 7'b1; // prevents illegal starting state = 7'b0; + end // set preamble length for the program run (always > 9 but < 26) - always_comb begin - pre_length = 10;//$random>>10 ; // number of space characters ahead of message; the >>10 changes the random value - if(pre_length < 10) pre_length = 10; // prevents pre_length < 10 + always_comb begin + pre_length = 10;//$random>>10 ; // number of space characters ahead of message; the >>10 changes the random value + if(pre_length < 10) pre_length = 10; // prevents pre_length < 10 else if(pre_length > 26) pre_length = 26; - end - + end + // ***** instantiate your own top level design here ***** top_level dut( .clk (clk ), // input: use your own port names, if different - .init (init ), // input: some prefer to call this ".reset" + .init (init ), // input: some prefer to call this ".reset" .req (start), // input: launch program .ack (done ) // output: "program run complete" ); - initial begin -//***** pre-load your instruction ROM here or inside itself ***** -// $readmemb("encoder.bin", dut.instr_rom.rom); -// you may also pre-load desired constants, etc. into -// your data_mem here -- the upper addresses are reserved for your use + initial begin +//***** pre-load your instruction ROM here or inside itself ***** +// $readmemb("encoder.bin", dut.instr_rom.rom); +// you may also pre-load desired constants, etc. into +// your data_mem here -- the upper addresses are reserved for your use // dut.data_mem.DM[128]=8'hfe; //whatever constants you want -// to display to console, change this line to file_no = 'b1; - file_no = 'b1; // display to console instead of file -// file_no = $fopen("msg_enocder_out.txt","w"); // create your output file +// to display to console, change this line to file_no = 'b1; + file_no = 'b1; // display to console instead of file +// file_no = $fopen("msg_enocder_out.txt","w"); // create your output file #0ns strlen = str1.len; // length of string 1 (# characters between " ") if(strlen>54) strlen = 54; // clip message at 54 characters // program 1 -- precompute encrypted message lfsr1[0] = LFSR_init; // any nonzero value (zero may be helpful for debug) $fdisplay(file_no,"run encryption program; original message = "); $fdisplay(file_no,"%s",str1); // print original message in transcript window - $fdisplay(file_no,"pt_no = %d",pt_no); + $fdisplay(file_no,"pt_no = %d",pt_no); $fdisplay(file_no,"LFSR_ptrn = 0x%h, LFSR_init = 0x%h",lfsr_ptrn,LFSR_init); - -// will subtract 0x20 from each preamble and each message character + +// will subtract 0x20 from each preamble and each message character for(int j=0; j<64; j++) // pre-fill message_padded with ASCII space characters msg_padded1[j] = 8'h20; // for(int l=0; l