├── .gitignore ├── LICENSE ├── README.md ├── risc.xise ├── risc_icf.ucf ├── schematic.jpg └── src ├── CPU_EU.v ├── Display_Controller.v ├── Hex_to_7Seg.v ├── IDP.v ├── IR.v ├── MemDumpCounter.v ├── PC.v ├── RISC_Processor.v ├── Register_File.v ├── alu.v ├── clk_500_Hz.v ├── cu.v ├── debounce.v ├── decoder3_to8.v ├── led_clk.v ├── led_controller.v ├── mux_8_to_1.v ├── ram1.v ├── reg16.v └── risc_top.v /.gitignore: -------------------------------------------------------------------------------- 1 | .log 2 | .txt 3 | 4 | ### OSX ### 5 | *.DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | 9 | # Icon must end with two \r 10 | Icon 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear in the root of a volume 16 | .DocumentRevisions-V100 17 | .fseventsd 18 | .Spotlight-V100 19 | .TemporaryItems 20 | .Trashes 21 | .VolumeIcon.icns 22 | .com.apple.timemachine.donotpresent 23 | 24 | # Directories potentially created on remote AFP share 25 | .AppleDB 26 | .AppleDesktop 27 | Network Trash Folder 28 | Temporary Items 29 | .apdisk 30 | 31 | ### XilinxISE ### 32 | # intermediate build files 33 | *.bgn 34 | *.bit 35 | *.bld 36 | *.cmd_log 37 | *.drc 38 | *.ll 39 | *.lso 40 | *.msd 41 | *.msk 42 | *.ncd 43 | *.ngc 44 | *.ngd 45 | *.ngr 46 | *.pad 47 | *.par 48 | *.pcf 49 | *.prj 50 | *.ptwx 51 | *.rbb 52 | *.rbd 53 | *.stx 54 | *.syr 55 | *.twr 56 | *.twx 57 | *.unroutes 58 | *.ut 59 | *.xpi 60 | *.xst 61 | *_bitgen.xwbt 62 | *_envsettings.html 63 | *_map.map 64 | *_map.mrp 65 | *_map.ngm 66 | *_map.xrpt 67 | *_ngdbuild.xrpt 68 | *_pad.csv 69 | *_pad.txt 70 | *_par.xrpt 71 | *_summary.html 72 | *_summary.xml 73 | *_usage.xml 74 | *_xst.xrpt 75 | 76 | # iMPACT generated files 77 | _impactbatch.log 78 | impact.xsl 79 | impact_impact.xwbt 80 | ise_impact.cmd 81 | webtalk_impact.xml 82 | 83 | # Core Generator generated files 84 | xaw2verilog.log 85 | 86 | # project-wide generated files 87 | *.gise 88 | par_usage_statistics.html 89 | usage_statistics_webtalk.html 90 | webtalk.log 91 | webtalk_pn.xml 92 | 93 | # generated folders 94 | iseconfig/ 95 | xlnx_auto_0_xdb/ 96 | xst/ 97 | _ngo/ 98 | _xmsgs/ 99 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Michael Rios 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 16-bit RISC Processor 2 | >A 16-bit Reduced Instruction Set Computing(RISC) processor designed using the Verilog harware description language(HDL). The design was implemented on a Nexys 4 DDR board using the Xilinx Artix-7 Field Programabble Gate Array(FPGA). The processor is capable of fetching and executing a set of 16-bit machine instructions. 3 | ### Schematic: 4 | ![](schematic.jpg) 5 | #### Memory Structure 6 | * 256 x 16 address space 7 | * Each memory location contains one 16-bit word 8 | #### Processor Register Set 9 | * Eight 16-bit integer registers (R0, R1, R2, R3, R4, R5, R6, R7) 10 | * 16-bit program counter (PC) 11 | * Flags Register (N, Z, C) 12 | #### Data Types 13 | * 16-bit word signed integer (-32768 :arrow_right: 32767) 14 | #### Addressing Modes 15 | 1. Immediate 16 | 2. Register 17 | 3. Register Indirect 18 | 4. PC relative 19 | #### Instruction Opcodes 20 | Basic format for instructions: 21 | 22 | | opcode | dest_reg | src1_reg | src2_reg | 23 | | :-------------:|:-------------:| :-------------:|:-------------:| 24 | | `bits 15 -> 9` | `bits 8 -> 6` |`bits 5 -> 3` |`bits 2 -> 0` | 25 | 26 | `Double-Source Operands`     `dest_reg` :arrow_left: `src1_reg` __operation__ `src2_reg` 27 | 28 | | Name | Opcode | 29 | | ------------- |:-------------:| 30 | | add | 111-0000 | 31 | | sub | 111-0001 | 32 | | cmp | 111-0010 | 33 | 34 | `Single-Source Operands`     `dest_reg` :arrow_left: __operation__ `src2_reg` 35 | 36 | | Name | Opcode | 37 | | ------------- |:-------------:| 38 | | mov | 111-0011 | 39 | | shl | 111-0100 | 40 | | shr | 111-0101 | 41 | | inc | 111-0110 | 42 | | dec | 111-0111 | 43 | 44 | `Load, Store & Halt` 45 | 46 | | Name | Opcode | 47 | | ------------- |:-------------:| 48 | | load | 111-1000 | 49 | | store | 111-1001 | 50 | | loadi | 111-1010 | 51 | | halt | 111-1011 | 52 | 53 | 54 | 55 | `Jumps` 56 | 57 | The address for conditional jump instructions is calculated by adding the 16-bit sign-extension of an 8-bit signed offset to the program counter. 58 | 59 | | opcode | 0 | 8-bit signed offset | 60 | | :-------------:|:-------------:| :-------------:| 61 | | `bits 15 -> 9` | `bit 8` |`bits 7 -> 0` | 62 | 63 | The address for unconditional jump instructions is specified by the contents of src2_reg. 64 | 65 | | opcode | | | src2_reg | 66 | | :-------------:|:-------------:| :-------------:|:-------------:| 67 | | `bits 15 -> 9` | `bits 8 -> 6` |`bits 5 -> 3` |`bits 2 -> 0` | 68 | 69 | | Name | Opcode | 70 | | ------------- |:-------------:| 71 | | je | 111-1100 | 72 | | jne | 111-1101 | 73 | | jc | 111-1110 | 74 | | jmp | 111-1111 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /risc.xise: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 |
150 | -------------------------------------------------------------------------------- /risc_icf.ucf: -------------------------------------------------------------------------------- 1 | ## Clock signal 2 | NET "clk" LOC = "E3" | IOSTANDARD = "LVCMOS33"; #Bank = 35, Pin name = #IO_L12P_T1_MRCC_35, Sch name = clk100mhz 3 | 4 | 5 | ## Switches 6 | NET "dump_mem" LOC=J15 | IOSTANDARD=LVCMOS33; #IO_L24N_T3_RS0_15 7 | 8 | ## Buttons 9 | NET "step_clk" LOC=P18 | IOSTANDARD=LVCMOS33; #IO_L9N_T1_DQS_D13_14 10 | NET "step_mem" LOC=P17 | IOSTANDARD=LVCMOS33; #IO_L12P_T1_MRCC_14 11 | NET "reset" LOC=M18 | IOSTANDARD=LVCMOS33; #IO_L4N_T0_D05_14 12 | 13 | 14 | ## LEDs 15 | NET "led[0]" LOC=H17 | IOSTANDARD=LVCMOS33; #IO_L18P_T2_A24_15 16 | NET "led[1]" LOC=K15 | IOSTANDARD=LVCMOS33; #IO_L24P_T3_RS1_15 17 | NET "led[2]" LOC=J13 | IOSTANDARD=LVCMOS33; #IO_L17N_T2_A25_15 18 | NET "led[3]" LOC=N14 | IOSTANDARD=LVCMOS33; #IO_L8P_T1_D11_14 19 | NET "led[4]" LOC=R18 | IOSTANDARD=LVCMOS33; #IO_L7P_T1_D09_14 20 | NET "led[5]" LOC=V17 | IOSTANDARD=LVCMOS33; #IO_L18N_T2_A11_D27_14 21 | NET "led[6]" LOC=U17 | IOSTANDARD=LVCMOS33; #IO_L17P_T2_A14_D30_14 22 | NET "led[7]" LOC=U16 | IOSTANDARD=LVCMOS33; #IO_L18P_T2_A12_D28_14 23 | 24 | 25 | ## 7 segment display 26 | NET "a" LOC=T10 | IOSTANDARD=LVCMOS33; #IO_L24N_T3_A00_D16_14 27 | NET "b" LOC=R10 | IOSTANDARD=LVCMOS33; #IO_25_14 28 | NET "c" LOC=K16 | IOSTANDARD=LVCMOS33; #IO_25_15 29 | NET "d" LOC=K13 | IOSTANDARD=LVCMOS33; #IO_L17P_T2_A26_15 30 | NET "e" LOC=P15 | IOSTANDARD=LVCMOS33; #IO_L13P_T2_MRCC_14 31 | NET "f" LOC=T11 | IOSTANDARD=LVCMOS33; #IO_L19P_T3_A10_D26_14 32 | NET "g" LOC=L18 | IOSTANDARD=LVCMOS33; #IO_L4P_T0_D04_14 33 | 34 | NET "an[0]" LOC=J17 | IOSTANDARD=LVCMOS33; #IO_L23P_T3_FOE_B_15 35 | NET "an[1]" LOC=J18 | IOSTANDARD=LVCMOS33; #IO_L23N_T3_FWE_B_15 36 | NET "an[2]" LOC=T9 | IOSTANDARD=LVCMOS33; #IO_L24P_T3_A01_D17_14 37 | NET "an[3]" LOC=J14 | IOSTANDARD=LVCMOS33; #IO_L19P_T3_A22_15 38 | NET "an[4]" LOC=P14 | IOSTANDARD=LVCMOS33; #IO_L8N_T1_D12_14 39 | NET "an[5]" LOC=T14 | IOSTANDARD=LVCMOS33; #IO_L14P_T2_SRCC_14 40 | NET "an[6]" LOC=K2 | IOSTANDARD=LVCMOS33; #IO_L23P_T3_35 41 | NET "an[7]" LOC=U13 | IOSTANDARD=LVCMOS33; #IO _L23N_T3_A02_D18_14 -------------------------------------------------------------------------------- /schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelriri/16-bit-risc-processor/6dc089b6f50f5f680fec15f461befd5ae914d113/schematic.jpg -------------------------------------------------------------------------------- /src/CPU_EU.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: CPU_EU.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.1 10 | * Rev. Date: November 18, 2016 11 | * 12 | * Purpose: This module instantiates all the modules that 13 | make up the CPU execution unit. That includes: Integer Datapath, 14 | PC, IR,and the adr_mux modules.The Execution Unit overall receives 15 | program instruction codes and data, and what it does is execute these 16 | instructions and data. 17 | * 18 | * Notes: Just like all of our previous "wrapper" modules, this module 19 | is written in structural verilog in order to inner connect all of the 20 | modules that make up the Execution unit. 21 | * 22 | ****************************************************************************/ 23 | `timescale 1ns / 1ps 24 | 25 | module CPU_EU(clk, reset, 26 | pc_ld, pc_sel, pc_inc, ir_ld, 27 | adr_sel, W_En, S_Sel, 28 | address, D_out, D_in, 29 | C, N, Z, 30 | W_Adr, R_Adr, S_Adr, Alu_Op, ir_out); //added these 31 | 32 | //IDP I/0: 33 | input clk, reset; 34 | input W_En; 35 | input [15:0] D_in; 36 | input [2:0] W_Adr, R_Adr, S_Adr; 37 | input [3:0] Alu_Op; 38 | input S_Sel; 39 | input pc_sel; 40 | output C, N, Z; 41 | output [15:0] D_out; 42 | output [15:0] ir_out; 43 | wire [15:0] reg_out; 44 | 45 | //PC I/0: 46 | input pc_ld, pc_inc; 47 | wire [15:0] pc_out; 48 | wire [15:0] pc_mux; 49 | //IR I/0: 50 | input ir_ld; 51 | //wire [15:0] ir_out; 52 | wire [15:0] sign_extension; 53 | wire [15:0] jaddr; 54 | //ADR_MUX: 55 | input adr_sel; 56 | output [15:0] address; 57 | 58 | // This instantiates the instruction register module. The IR module is a register that 59 | // stores instructions. In more detail, by storing an instruction in a register, we can 60 | // use the output of the register to control other parts of the CPU, so the instruction can 61 | // be executed. 62 | IR u0 (.clk(clk), .reset(reset), .Din(D_in), .Dout(ir_out), .ld(ir_ld)); 63 | 64 | // The block of code below instantiates the Integer Datapath module. This module is made 65 | // of the register file, alu, and a multiplexer. 66 | IDP u1 (.clk(clk), .reset(reset), .W_En(W_En), .W_Adr(W_Adr),.R_Adr(R_Adr), 67 | .S_Adr(S_Adr), .DS(D_in), .S_Sel(S_Sel), .C(C), .N(N), .Z(Z), .ALU_OP(Alu_Op), 68 | .Reg_Out(reg_out), .Alu_Out(D_out)); 69 | 70 | // This instantiates the Program counter module.The PC actually holds the address of the 71 | // current instruction being executed; however, once the instruction has completed, the PC 72 | // is updated with a new value for the next instruction. 73 | PC u2 (.clk(clk), .reset(reset), .ld(pc_ld), .incr(pc_inc), .Din(pc_mux), .Dout(pc_out)); 74 | 75 | // The assign statement below represents the address multiplexer 76 | // chooses the address to be The Reg_out output of the IDP or the 77 | // ALU-out of the ALU. 78 | assign address = (adr_sel) ? reg_out : pc_out; 79 | 80 | // The sign_extension is created using "replication" operator in verilog; the most significant 81 | // bit of the Instrucion is replicated 8 times to create a 16-bit output. 82 | assign sign_extension = { {8{ir_out[7]}}, ir_out[7:0]}; 83 | 84 | // The jump address is the PC added with the sign_extension. 85 | assign jaddr = pc_out + sign_extension; 86 | 87 | // The assign statement below represents the PC multiplexer 88 | // chooses the output to be the jaddr wire or the 89 | // ALU-out of the ALU. 90 | assign pc_mux = (pc_sel) ? D_out : jaddr; 91 | 92 | endmodule 93 | -------------------------------------------------------------------------------- /src/Display_Controller.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: Display_Controller.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.0 10 | * Rev. Date: November 15, 2016 11 | * 12 | * Purpose: This module will serve as a "wrapper" for the modules making up the 13 | display controller: the led clock, led controller, 8 to 1 multiplexer, and hex 14 | to 7 segment display modules. The modules will be instantiated into this block 15 | "Display Controller" module for ease of use in supsequent projects and 16 | applications. 17 | * 18 | * Notes: Instead of instantiating the modules in the top level, they are 19 | instantiated here to hide the details and ease the debugging process. 20 | * 21 | ****************************************************************************/ 22 | 23 | `timescale 1ns / 1ps 24 | 25 | module Display_Controller( clk, reset, seg0, seg1, seg2, seg3, seg4, 26 | seg5, seg6, seg7, an, a, b, c, d, e, f, g ); 27 | 28 | input clk, reset; 29 | input [3:0] seg0, seg1, seg2, seg3, seg4, seg5, seg6, seg7; 30 | output a, b, c, d, e, f, g; 31 | output [7:0] an; 32 | 33 | wire clk_out; 34 | wire [2:0] mux_sel; 35 | wire [3:0] mux_out; 36 | 37 | // This module instantiated below divides the 100MHz board clock to 38 | // a 480Hz clock necessary for refreshing the 7-Segment Displays. 39 | led_clk u0 (.clk_in(clk), .reset(reset), .clk_out(clk_out)); 40 | 41 | // The Led Controller uses the led clock to select one pixel at a time. 42 | // This module is an autonomous finite state maching that outputs a value 43 | // for select and asserts one anode at every state. 44 | led_controller u1 (.clk(clk_out), .reset(reset), .an(an), .seg_sel(mux_sel)); 45 | 46 | //This module will be incharch of sending a pixel its corresponding pixel data. 47 | mux_8_to_1 u2 (.d0(seg0), .d1(seg1), .d2(seg2), .d3(seg3), .d4(seg4), 48 | .d5(seg5), .d6(seg6), .d7(seg7), .sel(mux_sel), .Y(mux_out)); 49 | 50 | // This module controls the logic of the 7-segment display. 51 | Hex_to_7Seg u3 (.hex(mux_out), .a(a), .b(b), .c(c), .d(d), .e(e), .f(f), .g(g)); 52 | 53 | endmodule 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/Hex_to_7Seg.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: Hex_to_7Seg.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Rev. No.: Version 1.0 8 | * Rev. Date: November 5, 2016 9 | * 10 | * Purpose: This module controls the logic of the 7-segment display. When the 11 | input to the module(hex) contains a binary value of 0, then the 7segments on 12 | the FPGA will be manipulated in such a way to form a zero; if the input to 13 | the module(hex) contains a binary value of 1, then then the 7-segments on the 14 | FPGA will be manipulated to form a one; etc. This logic is achieved using a 15 | case statement. 16 | * 17 | * Notes: There exists two types of LED 7-segment displays: Common Cathode 18 | and Common Anode. Common Cathode displays have all cathodes tied together 19 | to logic "0" and the anodes are therefore illumianted through application of 20 | logic "1". In Common Anode displays, all anode connections are joined together 21 | to logic "1" and the individual segments are illuminated through application 22 | of a logic "0" signal. 23 | * The Nexys 4 DDR's 7-segment display uses common anode circuitry; therefore, the 24 | cathodes must be driven low to become illuminated. 25 | * 26 | ****************************************************************************/ 27 | 28 | `timescale 1ns / 1ps 29 | 30 | module Hex_to_7Seg( hex, a, b, c, d ,e, f, g ); 31 | 32 | input [3:0] hex; 33 | output reg a, b, c, d, e, f, g; 34 | 35 | always @(*) 36 | begin 37 | case(hex) 38 | 4'b0000: {a, b, c, d, e, f, g} = 7'b0000001; 39 | 4'b0001: {a, b, c, d, e, f, g} = 7'b1001111; 40 | 4'b0010: {a, b, c, d, e, f, g} = 7'b0010010; 41 | 4'b0011: {a, b, c, d, e, f, g} = 7'b0000110; 42 | 4'b0100: {a, b, c, d, e, f, g} = 7'b1001100; 43 | 4'b0101: {a, b, c, d, e, f, g} = 7'b0100100; 44 | 4'b0110: {a, b, c, d, e, f, g} = 7'b0100000; 45 | 4'b0111: {a, b, c, d, e, f, g} = 7'b0001111; 46 | 4'b1000: {a, b, c, d, e, f, g} = 7'b0000000; 47 | 4'b1001: {a, b, c, d, e, f, g} = 7'b0000100; 48 | 4'b1010: {a, b, c, d, e, f, g} = 7'b0001000; 49 | 4'b1011: {a, b, c, d, e, f, g} = 7'b1100000; 50 | 4'b1100: {a, b, c, d, e, f, g} = 7'b0110001; 51 | 4'b1101: {a, b, c, d, e, f, g} = 7'b1000010; 52 | 4'b1110: {a, b, c, d, e, f, g} = 7'b0110000; 53 | 4'b1111: {a, b, c, d, e, f, g} = 7'b0111000; 54 | default: {a, b, c, d, e, f, g} = 7'b0000000; 55 | endcase//case 56 | end//always 57 | endmodule 58 | 59 | -------------------------------------------------------------------------------- /src/IDP.v: -------------------------------------------------------------------------------- 1 | 2 | /****************************** C E C S 3 0 1 ****************************** 3 | * File Name: Integer_Datapath.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.1 10 | * Rev. Date: November 18, 2016 11 | * 12 | * Purpose: This module represents an Integer Datapath module. 13 | Basically an Integer Datapath module is made up of 14 | a register file, a S-mux, and an ALU. What this module 15 | does is that it transfers data from the register file 16 | like the R_Adr address to the ALU and S_Adr address to 17 | the ALU depending on the S-mux Seg_sel=0 or if Seg_sel=1 18 | than DS 16 bit data will go into the S input of the ALU. 19 | The ALU will do either a arithmetic operation or a 20 | logical operation,and than the ALU output will be displayed 21 | into the 7-segment display along with the R data in the 22 | register file and than it will store the Alu output into 23 | the register file. 24 | * 25 | * Notes: This module is written in a structural verilog. We used 26 | wires and instantiation in order to inner connect all 27 | the modules that are part of the Integer Datapath module. 28 | * 29 | ****************************************************************************/ 30 | 31 | `timescale 1ns / 1ps 32 | 33 | module IDP( clk, reset, W_En, W_Adr,R_Adr, S_Adr, DS, S_Sel, C, N, Z, ALU_OP, Reg_Out, Alu_Out); 34 | 35 | //Register File I/O: 36 | input clk, reset; 37 | input W_En; 38 | input [2:0] W_Adr; 39 | input [2:0] S_Adr; 40 | input [2:0] R_Adr; 41 | wire [15:0] S; 42 | output [15:0] Reg_Out; 43 | 44 | //S- MUX I/O: 45 | input S_Sel; 46 | input [15:0] DS; 47 | wire [15:0] mux_out; 48 | 49 | //ALU I/O: 50 | input [3:0] ALU_OP; 51 | output [15:0] Alu_Out; 52 | output C, N, Z; 53 | 54 | wire [15:0] S_Mux; 55 | 56 | // The module below insantiates the wrapper to the register file. This 8x16 register file 57 | // is made up of 8, 16-bit registers. The W(write) input will take in the output to the 58 | // ALU. 59 | Register_File u0 (.clk(clk), .reset(reset), .W_Adr(W_Adr), .we(W_En), .R_Adr(R_Adr), 60 | .S_Adr(S_Adr), .W(Alu_Out), .R(Reg_Out), .S(S)); 61 | 62 | // The code block below instantiates the Arithmatic Logic Unit (alu) module which is 63 | // responsible for performing various operations on 16-bit integers. 64 | alu u1 (.R(Reg_Out), .S(S_Mux), .Alu_op(ALU_OP), .Y(Alu_Out), 65 | .N(N), .Z(Z), .C(C)); 66 | 67 | // This assign statement will serve as a 2-to-1 multiplexer which decides when the S-input 68 | // to the ALU receives the S-output of the register file or DS based on the select. 69 | assign S_Mux = (S_Sel) ? DS : S; 70 | 71 | endmodule 72 | 73 | -------------------------------------------------------------------------------- /src/IR.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: IR.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.0 10 | * Rev. Date: November 18, 2016 11 | * 12 | * Purpose: This Instruction register module is a 16-bit register in a 13 | computer processor that contains the current instruction currently being 14 | executed. When the computer restarts or is reset,the program counter normally 15 | reverts to back to 0. 16 | * 17 | * Notes: 18 | ****************************************************************************/ 19 | `timescale 1ns / 1ps 20 | 21 | module IR(clk, reset,Din, Dout, ld); 22 | 23 | input clk, reset, ld; 24 | input [15:0] Din; 25 | output reg [15:0] Dout; 26 | 27 | // Behavioral section for writing to the register 28 | always @ ( posedge clk or posedge reset ) 29 | if (reset) 30 | Dout <= 16'b0; 31 | else 32 | if (ld) 33 | Dout <= Din; 34 | else Dout <= Dout; 35 | 36 | endmodule 37 | 38 | -------------------------------------------------------------------------------- /src/MemDumpCounter.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: MemDumpCounter.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.1 10 | * Rev. Date: November 28, 2016 11 | * 12 | * Purpose: This is a counter that we use in this lab as a way 13 | to insert an 16-bit address to the ram1 module when the top 14 | level address mux dump_mem = 1, if dump_mem = 0 than the output 15 | of this module will not be given to the address input of the ram1 16 | module. 17 | * 18 | * Notes: This is a basic up counter; We are also using he step_mem button 19 | , which comes from the top level, will be used as a way to increment this 20 | 16 bit counter by 1 at every positive edge. 21 | * 22 | ****************************************************************************/ 23 | `timescale 1ns / 1ps 24 | 25 | module MemDumpCounter( clk, reset, addr ); 26 | input clk, reset; 27 | output reg [15:0] addr; 28 | 29 | always @ (posedge clk or posedge reset) 30 | begin 31 | if (reset == 1'b1) 32 | addr <= 16'b0000_0000_0000_0000; 33 | else 34 | addr <= addr + 16'b0000_0000_0000_0001; 35 | end 36 | 37 | endmodule 38 | 39 | -------------------------------------------------------------------------------- /src/PC.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: PC.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.0 10 | * Rev. Date: November 18, 2016 11 | * 12 | * Purpose: This Program Counter module is a 16-bit register in a computer 13 | processor that contains the address/location of the instruction being 14 | executed at the current time. If the incr is enabled, the program 15 | counter increases its stored value by 1. When the computer restarts or is reset, 16 | the program counter normally reverts to back to 0. 17 | * 18 | * Notes: 19 | ****************************************************************************/ 20 | `timescale 1ns / 1ps 21 | 22 | module PC(clk, reset, ld, incr, Din, Dout); 23 | 24 | input clk, reset, ld, incr; 25 | input [15:0] Din; 26 | output reg [15:0] Dout; 27 | 28 | // Behavioral section for writing to the register 29 | always @ ( posedge clk or posedge reset ) 30 | if (reset) 31 | Dout <= 16'b0; 32 | else 33 | if (ld) 34 | Dout <= Din; 35 | else if (incr) 36 | Dout <= Dout + 1; 37 | else Dout <= Dout; 38 | 39 | endmodule 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/RISC_Processor.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: RISC_Processor.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.1 10 | * Rev. Date: November 28, 2016 11 | * 12 | * Purpose: This module represents a 16 bit RISC processor; 13 | Reduced Instruction Set Computing Processor. RISC is a CPU design strategy 14 | that implements much simpler instruction sets that require only one clock 15 | cycle to execute. These much simpler instructions require less transistors of 16 | hardware space which give more room for general purpose registers. 17 | * 18 | * Notes: In our module we only have a 16 bit RISC processor that is made up 19 | of the timing and control unit (CU) which is a moore implementation of a finite 20 | state machine and the CPU_Eu. The verilog code is implemented in basic structural 21 | verilog. 22 | * 23 | ****************************************************************************/ 24 | 25 | `timescale 1ns / 1ps 26 | 27 | module RISC_Processor(clk, reset, D_out, Address, D_in, mw_en, status); 28 | input clk, reset; 29 | input [15:0] D_in; 30 | output [15:0] D_out, Address; 31 | output [7:0] status; 32 | output mw_en; 33 | 34 | //wires: 35 | wire [15:0] ir_out; 36 | wire N, Z, C; 37 | wire [2:0] W_Adr, R_Adr, S_Adr; 38 | wire adr_sel, s_sel; 39 | wire pc_ld, pc_inc, pc_sel, ir_ld; 40 | wire rw_en; 41 | wire [3:0] Alu_Op; 42 | 43 | // This instantiates the Control Unit module. We use this as a way to inner 44 | // connect the wires,inputs,and outputs from this module to the inputs,outputs 45 | // and wires from the control unit module. 46 | cu u0 ( .clk(clk), .reset(reset), .IR(ir_out), .N(N), .Z(Z), .C(C), 47 | .W_Adr(W_Adr), .R_Adr(R_Adr), .S_Adr(S_Adr), 48 | .adr_sel(adr_sel), .s_sel(s_sel), 49 | .pc_ld(pc_ld), .pc_inc(pc_inc), .pc_sel(pc_sel), .ir_ld(ir_ld), 50 | .mw_en(mw_en), .rw_en(rw_en), .alu_op(Alu_Op), .status(status)); 51 | 52 | // This instantiates the CPU_EU module that we use in order to inner connects 53 | // the I/O and wires of this module to the I/O and wires from the cpu_eu. 54 | CPU_EU u1 ( .clk(clk), .reset(reset), 55 | .pc_ld(pc_ld), .pc_sel(pc_sel), .pc_inc(pc_inc), .ir_ld(ir_ld), 56 | .adr_sel(adr_sel), .W_En(rw_en), .S_Sel(s_sel), 57 | .address(Address), .D_out(D_out), .D_in(D_in), .C(C), .N(N), .Z(Z), 58 | .W_Adr(W_Adr), .R_Adr(R_Adr), .S_Adr(S_Adr), .Alu_Op(Alu_Op), .ir_out(ir_out)); 59 | 60 | endmodule 61 | -------------------------------------------------------------------------------- /src/Register_File.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: Register_File.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.0 10 | * Rev. Date: November 18, 2016 11 | * 12 | * Purpose: This module instantiates all of the modules that make up the 13 | register file. That includes 3 instantiations of a 3-to 8 decoder that 14 | will be used as register selection done with W_Adr R_Adr and S_Adr, and 15 | eight instances of a 16 bit register. 16 | * 17 | * Notes: Like the top level module, this module is also written in structural 18 | verilog, which is the easiest method to connect all module of the register 19 | file together. Since it is a structural module, we use wires in order to 20 | inner connect the load,oea, and oeb wires to its certain instantiation. 21 | * 22 | ****************************************************************************/ 23 | 24 | `timescale 1ns / 1ps 25 | 26 | module Register_File( clk, reset, W_Adr, we, R_Adr, S_Adr, W, R, S ); 27 | 28 | input clk, reset; 29 | input we; 30 | input [2:0] W_Adr; 31 | input [2:0] R_Adr; 32 | input [2:0] S_Adr; 33 | input [15:0] W; 34 | output [15:0] R; 35 | output [15:0] S; 36 | 37 | wire r7_ld, r7_oea, r7_oeb; 38 | wire r6_ld, r6_oea, r6_oeb; 39 | wire r5_ld, r5_oea, r5_oeb; 40 | wire r4_ld, r4_oea, r4_oeb; 41 | wire r3_ld, r3_oea, r3_oeb; 42 | wire r2_ld, r2_oea, r2_oeb; 43 | wire r1_ld, r1_oea, r1_oeb; 44 | wire r0_ld, r0_oea, r0_oeb; 45 | 46 | 47 | decoder3_to8 48 | W_dec (.in(W_Adr), .enable(we), 49 | .y({r7_ld,r6_ld, r5_ld,r4_ld,r3_ld,r2_ld,r1_ld,r0_ld})), 50 | 51 | R_dec (.in(R_Adr), .enable(1'b1), 52 | .y({r7_oea, r6_oea,r5_oea, r4_oea, r3_oea, r2_oea, r1_oea, r0_oea})), 53 | 54 | S_dec (.in(S_Adr), .enable(1'b1), 55 | .y({r7_oeb, r6_oeb,r5_oeb, r4_oeb, r3_oeb, r2_oeb, r1_oeb, r0_oeb})); 56 | 57 | reg16 58 | R7 (.clk(clk), .reset(reset), .Din(W), .ld(r7_ld), .oeA(r7_oea), .oeB(r7_oeb),.DA(R), .DB(S)), 59 | R6 (.clk(clk), .reset(reset), .Din(W), .ld(r6_ld), .oeA(r6_oea), .oeB(r6_oeb),.DA(R), .DB(S)), 60 | R5 (.clk(clk), .reset(reset), .Din(W), .ld(r5_ld), .oeA(r5_oea), .oeB(r5_oeb),.DA(R), .DB(S)), 61 | R4 (.clk(clk), .reset(reset), .Din(W), .ld(r4_ld), .oeA(r4_oea), .oeB(r4_oeb),.DA(R), .DB(S)), 62 | R3 (.clk(clk), .reset(reset), .Din(W), .ld(r3_ld), .oeA(r3_oea), .oeB(r3_oeb),.DA(R), .DB(S)), 63 | R2 (.clk(clk), .reset(reset), .Din(W), .ld(r2_ld), .oeA(r2_oea), .oeB(r2_oeb),.DA(R), .DB(S)), 64 | R1 (.clk(clk), .reset(reset), .Din(W), .ld(r1_ld), .oeA(r1_oea), .oeB(r1_oeb),.DA(R), .DB(S)), 65 | R0 (.clk(clk), .reset(reset), .Din(W), .ld(r0_ld), .oeA(r0_oea), .oeB(r0_oeb),.DA(R), .DB(S)); 66 | 67 | endmodule 68 | -------------------------------------------------------------------------------- /src/alu.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * File Name: alu.v 3 | * Project: Lab Project 7: CPU Execution Unit 4 | * Designer 1: Michael Rios 5 | * Email: riosmichael28@ymail.com 6 | * Designer 2: Yuliana Uriostegui 7 | * Email: yulove613@gmail.com 8 | * Rev. No.: Version 1.1 9 | * Rev. Date: November 5, 2016 10 | * 11 | * Purpose: This module represents a Arithmetic Logic Unit (ALU). 12 | The Alu unit is a very important part of a computer's 13 | central processing unit. Its function is to perform 14 | arithmetic and logic operations on the values that are held 15 | in the registers. In this case we have a 16-bit Alu, which 16 | means we are performing a variety of manipulations on 16 bit 17 | integers. In this case, we are only performing 13 different 18 | operations. 19 | * 20 | * Notes: This module is written in behavioral verilog. R and S both 21 | represent the data that has the contents of the register 22 | addressed by the R_Adr and S_Adr of the register file. 23 | In the Alu R and S data will be used in order to perform 24 | various manipulations of this data. Alu_op is an input that 25 | will come from 4 of our switches in Nexys 4 board. Y is the 26 | ouput of the ALU and basically its content to display depends 27 | on the Alu_op, S_Adr, and S_sel inputs. 28 | * 29 | ****************************************************************************/ 30 | /**************************************************************************** 31 | * Written by: R. W. Allison 32 | * Date: July 20, 2016 33 | * File: 301_alu.v 34 | * 35 | * This 16-bit ALU will be used in the 301 "Integer Datapath" project 36 | * to perform various manipulations on 16-bit integers. 37 | * There are 4 "Op" inputs to perform up to 16 basic operations. 38 | * Currently, there are only 13 of the 16 operations used. 39 | * 40 | * The alu status flags represent the Y output being negative (N), 41 | * zero(Z), and a carry out (C). 42 | ****************************************************************************/ 43 | `timescale 1ns / 1ps 44 | 45 | module alu ( R, S, Alu_op, Y, N, Z, C ); 46 | 47 | input [15:0] R, S; 48 | input [3:0] Alu_op; 49 | output [15:0] Y; reg [15:0] Y; 50 | output N, Z, C; reg [15:0] N, Z, C; 51 | 52 | always @(R or S or Alu_op)begin 53 | case (Alu_op) 54 | 4'b0000 : {C, Y} = {1'b0, S}; // pass S 55 | 4'b0001 : {C, Y} = {1'b0, R}; // pass R 56 | 4'b0010 : {C, Y} = S + 1; // increment S 57 | 4'b0011 : {C, Y} = S - 1; // decrement S 58 | 4'b0100 : {C, Y} = R + S; // add 59 | 4'b0101 : {C, Y} = R - S; // Subtract 60 | 4'b0110 : begin // right shift S (logic) 61 | C = S[0]; 62 | Y = S >> 1; 63 | end 64 | 4'b0111 : begin 65 | C = S[15]; // left shift S (logic) 66 | Y = S << 1; 67 | end 68 | 4'b1000 : {C, Y} = {1'b0, R & S}; // logic and 69 | 4'b1001 : {C, Y} = {1'b0, R | S}; // logic or 70 | 4'b1010 : {C, Y} = {1'b0, R ^ S}; // logic xor 71 | 4'b1011 : {C, Y} = {1'b0, ~S}; // logic not S (1's comp) 72 | 4'b1100 : {C, Y} = 0 - S; // negate S (2's comp) 73 | default : {C, Y} = {1'b0, S}; // pass S for default 74 | endcase 75 | 76 | //handle last two status flags 77 | N = Y[15]; 78 | if (Y == 16'b0) 79 | Z = 1'b1; 80 | else 81 | Z = 1'b0; 82 | 83 | end //end always 84 | 85 | endmodule 86 | 87 | -------------------------------------------------------------------------------- /src/clk_500_Hz.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: clk_500_Hz.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.1 10 | * Rev. Date: November 18, 2016 11 | * 12 | * Purpose: Generally, the purpose of the a clock divider is to take 13 | an input clock with a specific frequency and produce a desired output 14 | clock and frequency. We achieved this by dividing the incoming clock 15 | by the decimalvalue in the if-statement. In this case, since the desired 16 | outgoing frequency is 500HZ and the incoming frequency is the 100MHz provided 17 | by the FPGA. This decimal value was achieved by dividing the incoming 18 | frequency by the outgoing frequency and dividing by two to make half a period. 19 | * 20 | * Notes: The resulting value inside the if-statement is 100,000. 21 | * 22 | ****************************************************************************/ 23 | 24 | `timescale 1ns / 1ps 25 | 26 | module clk_500_Hz( clk_in, reset, clk_out ); 27 | 28 | input clk_in, reset; 29 | output clk_out; 30 | reg clk_out; 31 | integer i; 32 | //*************************************************************** 33 | // The following verilog code will "divide" an incoming clock 34 | // by the 32-bit decimal value specified in the "if condition" 35 | // 36 | // The value of the timer that counts the incoming clock ticks 37 | // is equal to [ (Incoming Freq / Outgoing Freq) / 2 ] 38 | //*************************************************************** 39 | 40 | always@ (posedge clk_in or posedge reset) begin 41 | if (reset == 1'b1) begin 42 | i = 0; 43 | clk_out = 0; 44 | end 45 | //got a clock, so increment the counter and 46 | //test to see if half a period has elapsed 47 | else begin 48 | i = i+1; 49 | if (i >= ((100000000/500)/2)) begin 50 | clk_out = ~clk_out; 51 | i=0; 52 | end//if 53 | end//else 54 | end //always 55 | 56 | endmodule 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/cu.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: cu.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.1 10 | * Rev. Date: November 18, 2016 11 | * 12 | * Purpose: This is the control unit verilog code. The control unit (CU) 13 | is a component of a computer's central processing unit. What the control 14 | unit does is that it directs operation of the processor. This is why it 15 | is a finite state machine, because it has different states main ones being 16 | fetch, decode, and execute. The control unit is in charge of things like 17 | telling the computer's memory, arithmetic/logic unit, and input and output 18 | devices how to respond to a program's instructions. 19 | * 20 | * Notes: Parameters were used in order to make the code more readible and 21 | simplified. 22 | * 23 | ****************************************************************************/ 24 | /**************************************************************************** 25 | * Date: November 18, 2016 26 | * File: cu.v 27 | * 28 | * A "Moore" finite state machine that implements the major cycles for 29 | * fetching and executing instructions for the 301 16-bit RISC Processor. 30 | ****************************************************************************/ 31 | `timescale 1ns / 1ps 32 | //************************************************************************** 33 | module cu(clk, reset, IR, N, Z, C, // conrol unit inputs 34 | W_Adr, R_Adr, S_Adr, // these are 35 | adr_sel, s_sel, // the control 36 | pc_ld, pc_inc, pc_sel, ir_ld, // word outputs 37 | mw_en, rw_en, alu_op, // fields 38 | status); // LED outputs 39 | //************************************************************************** 40 | 41 | input clk, reset; // clock and reset 42 | input [15:0] IR; // instruction register input 43 | input N, Z, C; // datapath status inputs 44 | output [2:0] W_Adr, R_Adr, S_Adr; // register file address outputs 45 | output adr_sel, s_sel; // mux select outputs 46 | output pc_ld, pc_inc, pc_sel, ir_ld; // pc_load, pcinc, pc select, ir load 47 | output mw_en, rw_en; // memory_write, register_file write 48 | output [3:0] alu_op; // ALU opcode output 49 | output [7:0] status; // 8 LED outputs to display current state 50 | 51 | /*************************** 52 | * data structures * 53 | ***************************/ 54 | 55 | reg [2:0] W_Adr, R_Adr, S_Adr; // these 12 56 | reg adr_sel, s_sel; // fields 57 | reg pc_ld, pc_inc; // make up 58 | reg pc_sel, ir_ld; // the 59 | reg mw_en, rw_en; // control word 60 | reg [3:0] alu_op; // of the control unit 61 | 62 | reg [4:0] state; // present state register 63 | reg [4:0] nextstate; // next state register 64 | reg [7:0] status; // LED status/ state outputs 65 | reg ps_N, ps_Z, ps_C; // present state flags register 66 | reg ns_N, ns_Z, ns_C; // next state flags register 67 | 68 | parameter RESET = 0, FETCH = 1, DECODE = 2, 69 | ADD = 3, SUB = 4, CMP = 5, MOV = 6, 70 | INC = 7, DEC = 8, SHL = 9, SHR = 10, 71 | LD = 11, STO = 12, LDI = 13, 72 | JE = 14, JNE = 15, JC = 16, JMP = 17, 73 | HALT = 18, 74 | ILLEGAL_OP = 31; 75 | 76 | 77 | /************************************ 78 | * 301 Control Unit Sequencer * 79 | *************************************/ 80 | 81 | // synchronous state register assignment 82 | always @ ( posedge clk or posedge reset ) 83 | if (reset) 84 | state = RESET; 85 | else 86 | state = nextstate; 87 | 88 | // synchronous flags for register assignment 89 | always @ ( posedge clk or posedge reset ) 90 | if (reset) 91 | {ps_N, ps_Z, ps_C} = 3'b0; 92 | else 93 | {ps_N, ps_Z, ps_C} = {ns_N, ns_Z, ns_C}; 94 | 95 | // combinational logic section for both next state logic 96 | // and control word outputs for cpu_execution_unit and memory 97 | always @( state ) 98 | case ( state ) 99 | 100 | RESET: begin // Default Control Word Values -- LED pattern = 1111_1111 101 | W_Adr = 3'b000; R_Adr = 3'b000; S_Adr = 3'b000; 102 | adr_sel = 1'b0; s_sel = 1'b0; 103 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 104 | mw_en = 1'b0; rw_en = 1'b0; alu_op = 4'b0000; 105 | {ns_N, ns_Z, ns_C} = 3'b0; 106 | status = 8'hFF; 107 | nextstate = FETCH; 108 | end 109 | 110 | FETCH: begin // IR <-- M[PC], PC <- PC + 1 -- LED pattern = 1000_0000 111 | W_Adr = 3'b000; R_Adr = 3'b000; S_Adr = 3'b000; 112 | adr_sel = 1'b0; s_sel = 1'b0; 113 | pc_ld = 1'b0; pc_inc = 1'b1; pc_sel = 1'b0; ir_ld = 1'b1; 114 | mw_en = 1'b0; rw_en = 1'b0; alu_op = 4'b0000; 115 | {ns_N, ns_Z, ns_C} = {ps_N, ps_Z, ps_C}; // flags remain the same 116 | status = 8'h80; 117 | nextstate = DECODE; 118 | end 119 | 120 | DECODE: begin // Default Control Word, NS <- case ( IR[15:9] ) -- LED pattern = 1100_0000 121 | W_Adr = 3'b000; R_Adr = 3'b000; S_Adr = 3'b000; 122 | adr_sel = 1'b0; s_sel = 1'b0; 123 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 124 | mw_en = 1'b0; rw_en = 1'b0; alu_op = 4'b0000; 125 | {ns_N, ns_Z, ns_C} = {ps_N, ps_Z, ps_C}; // flags remain the same 126 | status = 8'hC0; 127 | case ( IR[15:9] ) 128 | 7'h70: nextstate = ADD; 129 | 7'h71: nextstate = SUB; 130 | 7'h72: nextstate = CMP; 131 | 7'h73: nextstate = MOV; 132 | 7'h74: nextstate = SHL; 133 | 7'h75: nextstate = SHR; 134 | 7'h76: nextstate = INC; 135 | 7'h77: nextstate = DEC; 136 | 7'h78: nextstate = LD; 137 | 7'h79: nextstate = STO; 138 | 7'h7A: nextstate = LDI; 139 | 7'h7B: nextstate = HALT; 140 | 7'h7C: nextstate = JE; 141 | 7'h7D: nextstate = JNE; 142 | 7'h7E: nextstate = JC; 143 | 7'h7F: nextstate = JMP; 144 | default: nextstate = ILLEGAL_OP; 145 | endcase 146 | end 147 | 148 | ADD: begin // R[IR[8:6]] <- R[IR[5:3]] + R[IR[2:0]] -- LED pattern = {ps_N, ps_Z, ps_C, 5'b00000} 149 | W_Adr = IR[8:6]; R_Adr = IR[5:3]; S_Adr = IR[2:0]; 150 | adr_sel = 1'b0; s_sel = 1'b0; 151 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 152 | mw_en = 1'b0; rw_en = 1'b1; alu_op = 4'b0100; 153 | {ns_N, ns_Z, ns_C} = {N, Z, C}; 154 | status = {ps_N, ps_Z, ps_C, 5'b00000}; 155 | nextstate = FETCH; 156 | end 157 | 158 | SUB: begin // R[IR[8:6]] <- R[IR[5:3]] - R[IR[2:0]] -- LED pattern = {ps_N, ps_Z, ps_C, 5'b00001} 159 | W_Adr = IR[8:6]; R_Adr = IR[5:3]; S_Adr = IR[2:0]; 160 | adr_sel = 1'b0; s_sel = 1'b0; 161 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 162 | mw_en = 1'b0; rw_en = 1'b1; alu_op = 4'b0101; 163 | {ns_N, ns_Z, ns_C} = {N, Z, C}; 164 | status = {ps_N, ps_Z, ps_C, 5'b00001}; 165 | nextstate = FETCH; 166 | end 167 | 168 | CMP: begin // {N, Z, C} <- R[IR[5:3]] - R[IR[2:0]] -- LED pattern = {ps_N, ps_Z, ps_C, 5'b00010} 169 | W_Adr = 3'b000; R_Adr = IR[5:3]; S_Adr = IR[2:0]; 170 | adr_sel = 1'b0; s_sel = 1'b0; 171 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 172 | mw_en = 1'b0; rw_en = 1'b0; alu_op = 4'b0101; 173 | {ns_N, ns_Z, ns_C} = {N, Z, C}; 174 | status = {ps_N, ps_Z, ps_C, 5'b00010}; 175 | nextstate = FETCH; 176 | end 177 | 178 | MOV: begin // R[IR[8:6]] <- R[IR[2:0]] -- LED pattern = {ps_N, ps_Z, ps_C, 5'b00011} 179 | W_Adr = IR[8:6]; R_Adr = 3'b000; S_Adr = IR[2:0]; 180 | adr_sel = 1'b0; s_sel = 1'b0; 181 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 182 | mw_en = 1'b0; rw_en = 1'b1; alu_op = 4'b0000; 183 | {ns_N, ns_Z, ns_C} = {ps_N, ps_Z, ps_C}; 184 | status = {ps_N, ps_Z, ps_C, 5'b00011}; 185 | nextstate = FETCH; 186 | end 187 | 188 | SHL: begin // R[IR[8:6]] <- R[IR[2:0]] << 1 -- LED pattern = {ps_N, ps_Z, ps_C, 5'b00100} 189 | W_Adr = IR[8:6]; R_Adr = 3'b000; S_Adr = IR[2:0]; 190 | adr_sel = 1'b0; s_sel = 1'b0; 191 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 192 | mw_en = 1'b0; rw_en = 1'b1; alu_op = 4'b0111; 193 | {ns_N, ns_Z, ns_C} = {N, Z, C}; 194 | status = {ps_N, ps_Z, ps_C, 5'b00100}; 195 | nextstate = FETCH; 196 | end 197 | 198 | SHR: begin // R[IR[8:6]] <- R[IR[2:0]] >> 1 -- LED pattern = {ps_N, ps_Z, ps_C, 5'b00101} 199 | W_Adr = IR[8:6]; R_Adr = 3'b000; S_Adr = IR[2:0]; 200 | adr_sel = 1'b0; s_sel = 1'b0; 201 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 202 | mw_en = 1'b0; rw_en = 1'b1; alu_op = 4'b0110; 203 | {ns_N, ns_Z, ns_C} = {N, Z, C}; 204 | status = {ps_N, ps_Z, ps_C, 5'b00101}; 205 | nextstate = FETCH; 206 | end 207 | 208 | INC: begin // R[IR[8:6]] <- R[IR[2:0]] + 1 -- LED pattern = {ps_N, ps_Z, ps_C, 5'b00110} 209 | W_Adr = IR[8:6]; R_Adr = 3'b000; S_Adr = IR[2:0]; 210 | adr_sel = 1'b0; s_sel = 1'b0; 211 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 212 | mw_en = 1'b0; rw_en = 1'b1; alu_op = 4'b0010; 213 | {ns_N, ns_Z, ns_C} = {N, Z, C}; 214 | status = {ps_N, ps_Z, ps_C, 5'b00110}; 215 | nextstate = FETCH; 216 | end 217 | 218 | DEC: begin // R[IR[8:6]] <- R[IR[2:0]] - 1 -- LED pattern = {ps_N, ps_Z, ps_C, 5'b00111} 219 | W_Adr = IR[8:6]; R_Adr = 3'b000; S_Adr = IR[2:0]; 220 | adr_sel = 1'b0; s_sel = 1'b0; 221 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 222 | mw_en = 1'b0; rw_en = 1'b1; alu_op = 4'b0011; 223 | {ns_N, ns_Z, ns_C} = {N, Z, C}; 224 | status = {ps_N, ps_Z, ps_C, 5'b00111}; 225 | nextstate = FETCH; 226 | end 227 | 228 | LD: begin // R[IR[8:6]] <- M[ R[ IR[2:0] ] ]-- LED pattern = {ps_N, ps_Z, ps_C, 5'b01000} 229 | W_Adr = IR[8:6]; R_Adr = IR[2:0]; S_Adr = 3'b000; 230 | adr_sel = 1'b1; s_sel = 1'b1; 231 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 232 | mw_en = 1'b0; rw_en = 1'b1; alu_op = 4'b0000; 233 | {ns_N, ns_Z, ns_C} = {ps_N, ps_Z, ps_C}; 234 | status = {ps_N, ps_Z, ps_C, 5'b01000}; 235 | nextstate = FETCH; 236 | end 237 | 238 | STO: begin // M[IR[8:6]] <- R[IR[2:0]] -- LED pattern = {ps_N, ps_Z, ps_C, 5'b01001} 239 | W_Adr = 3'b000; R_Adr = IR[8:6]; S_Adr = IR[2:0]; 240 | adr_sel = 1'b1; s_sel = 1'b0; 241 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 242 | mw_en = 1'b1; rw_en = 1'b0; alu_op = 4'b0000; 243 | {ns_N, ns_Z, ns_C} = {ps_N, ps_Z, ps_C}; 244 | status = {ps_N, ps_Z, ps_C, 5'b01001}; 245 | nextstate = FETCH; 246 | end 247 | 248 | LDI: begin // R[IR[8:6]] <- M[PC], PC <- PC + 1 -- LED pattern = {ps_N, ps_Z, ps_C, 5'b01010} 249 | W_Adr = IR[8:6]; R_Adr = 3'b000; S_Adr = 3'b000; 250 | adr_sel = 1'b0; s_sel = 1'b1; 251 | pc_ld = 1'b0; pc_inc = 1'b1; pc_sel = 1'b0; ir_ld = 1'b0; 252 | mw_en = 1'b0; rw_en = 1'b1; alu_op = 4'b0000; 253 | {ns_N, ns_Z, ns_C} = {ps_N, ps_Z, ps_C}; 254 | status = {ps_N, ps_Z, ps_C, 5'b01010}; 255 | nextstate = FETCH; 256 | end 257 | 258 | JE: begin // if (ps_Z=1) PC <-- PC+se_IR[7:0] else PC <- PC -- LED pattern = {ps_N, ps_Z, ps_C, 5'b01100} 259 | W_Adr = 3'b000; R_Adr = 3'b000; S_Adr = 3'b000; 260 | adr_sel = 1'b0; s_sel = 1'b0; 261 | pc_ld = ps_Z; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 262 | mw_en = 1'b0; rw_en = 1'b0; alu_op = 4'b0000; 263 | {ns_N, ns_Z, ns_C} = {ps_N, ps_Z, ps_C}; 264 | status = {ps_N, ps_Z, ps_C, 5'b01100}; 265 | nextstate = FETCH; 266 | end 267 | 268 | JNE: begin // if (ps_Z=0) PC <-- PC+se_IR[7:0] else PC <- PC -- LED pattern = {ps_N, ps_Z, ps_C, 5'b01101} 269 | W_Adr = 3'b000; R_Adr = 3'b000; S_Adr = 3'b000; 270 | adr_sel = 1'b0; s_sel = 1'b0; 271 | pc_ld = !ps_Z; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 272 | mw_en = 1'b0; rw_en = 1'b0; alu_op = 4'b0000; 273 | {ns_N, ns_Z, ns_C} = {ps_N, ps_Z, ps_C}; 274 | status = {ps_N, ps_Z, ps_C, 5'b01101}; 275 | nextstate = FETCH; 276 | end 277 | 278 | JC: begin // if (ps_C=1) PC <-- PC+se_IR[7:0] else PC <- PC -- LED pattern = {ps_N, ps_Z, ps_C, 5'b01110} 279 | W_Adr = 3'b000; R_Adr = 3'b000; S_Adr = 3'b000; 280 | adr_sel = 1'b0; s_sel = 1'b0; 281 | pc_ld = ps_C; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 282 | mw_en = 1'b0; rw_en = 1'b0; alu_op = 4'b0000; 283 | {ns_N, ns_Z, ns_C} = {ps_N, ps_Z, ps_C}; 284 | status = {ps_N, ps_Z, ps_C, 5'b01110}; 285 | nextstate = FETCH; 286 | end 287 | 288 | JMP: begin // PC <- R[IR[2:0]] -- LED pattern = {ps_N, ps_Z, ps_C, 5'b01111} 289 | W_Adr = 3'b000; R_Adr = 3'b000; S_Adr = IR[2:0]; 290 | adr_sel = 1'b0; s_sel = 1'b0; 291 | pc_ld = 1'b1; pc_inc = 1'b0; pc_sel = 1'b1; ir_ld = 1'b0; 292 | mw_en = 1'b0; rw_en = 1'b0; alu_op = 4'b0000; 293 | {ns_N, ns_Z, ns_C} = {ps_N, ps_Z, ps_C}; 294 | status = {ps_N, ps_Z, ps_C, 5'b01111}; 295 | nextstate = FETCH; 296 | end 297 | 298 | HALT: begin // Default Control Word Values -- LED pattern = {ps_N, ps_Z, ps_C, 5'b01011} 299 | W_Adr = 3'b000; R_Adr = 3'b000; S_Adr = 3'b000; 300 | adr_sel = 1'b0; s_sel = 1'b0; 301 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 302 | mw_en = 1'b0; rw_en = 1'b0; alu_op = 4'b0000; 303 | {ns_N, ns_Z, ns_C} = 3'b0; 304 | status = {ps_N, ps_Z, ps_C, 5'b01011} ; 305 | nextstate = HALT; // Loop here forever 306 | end 307 | 308 | ILLEGAL_OP: begin // Default Control Word Values -- LED pattern = 1111_0000 309 | W_Adr = 3'b000; R_Adr = 3'b000; S_Adr = 3'b000; 310 | adr_sel = 1'b0; s_sel = 1'b0; 311 | pc_ld = 1'b0; pc_inc = 1'b0; pc_sel = 1'b0; ir_ld = 1'b0; 312 | mw_en = 1'b0; rw_en = 1'b0; alu_op = 4'b0000; 313 | {ns_N, ns_Z, ns_C} = 3'b0; 314 | status = 8'hF0; 315 | nextstate = ILLEGAL_OP; // Loop here forever 316 | end 317 | endcase 318 | 319 | endmodule 320 | 321 | 322 | -------------------------------------------------------------------------------- /src/debounce.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: debounce.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.1 10 | * Rev. Date: November 18, 2016 11 | * 12 | * Purpose: The purpose of this module is to counteract the bounce 13 | associated with using mechanical switches. When the contacts of any 14 | mechanical switch make contact they rebound(or bounce) before coming 15 | to a rest. This module counteracts this behavior by waiting this bounce 16 | out; filtering out all unstable inputs. We do this by shifting the 17 | input into a register which will, in our case, wait out the unstable 18 | inputs for about 20ms --since our frequency is 500HZ. The next step, the 19 | assign statement, creates the one-shot pulse which will serve as out 20 | output. When all samples in the register are 1, that siginifies that the 21 | inputs are stable. The reason that q9 is complemented is due to the fact 22 | that we are only trying to output one clock pulse. When the oldest sample 23 | is complemented, in this case q9, it will create this effect as all samples 24 | will be 1 for only one clock pulse. 25 | * 26 | * Notes: 27 | * 28 | ****************************************************************************/ 29 | 30 | `timescale 1ns / 1ps 31 | 32 | module debounce( clk_in, reset, D_in, D_out ); 33 | 34 | input clk_in, reset, D_in; 35 | output D_out; 36 | wire D_out; 37 | 38 | reg q9, q8, q7, q6, q5, q4, q3, q2, q1, q0; 39 | 40 | always @ ( posedge clk_in or posedge reset) 41 | if (reset == 1'b1) 42 | {q9, q8, q7, q6, q5, q4, q3, q2, q1, q0} <= 10'b0; 43 | else begin 44 | //Shift in the new sample that's on the D_in input. 45 | q9 <= q8; q8 <= q7; q7 <= q6; q6 <= q5; q5 <= q4; 46 | q4 <= q3; q3 <= q2; q2<=q1; q1 <= q0; q0 <= D_in; 47 | end 48 | //Create the debounced, one-shot pulse. 49 | assign D_out = !q9 & q8 & q7 & q6 & q5 & 50 | q4 & q3 & q2 & q1 & q0; 51 | 52 | endmodule 53 | 54 | -------------------------------------------------------------------------------- /src/decoder3_to8.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: decoder3_to8.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.0 10 | * Rev. Date: November 18, 2016 11 | * 12 | * Purpose: The purpose of this module represents a 3-8 decoder that 13 | we will need in order to have register selection done with the W_Adr, R_Adr 14 | and S_Adr address inputs. 15 | * 16 | * Notes: This 3-8 decoder is written in behavioral verilog that uses an 17 | always block and a case statement since a decoder will only output only 18 | one byte depending on the 3 bit input enters the decoder. two of the 19 | three decoders will always be enabled while the otherwhich is the decoder 20 | the is in control of the W_Adr will only be enabled when we push the btn_down 21 | of the Nexys 4 board. 22 | * 23 | ****************************************************************************/ 24 | 25 | `timescale 1ns / 1ps 26 | 27 | module decoder3_to8( in, enable, y ); 28 | 29 | input [2:0] in; 30 | input enable; 31 | output reg [7:0] y; 32 | 33 | always @(in or enable) begin 34 | y = 8'b00000000; 35 | if(enable == 1) begin 36 | case(in) 37 | 3'b000 : y = 8'b00000001; 38 | 3'b001 : y = 8'b00000010; 39 | 3'b010 : y = 8'b00000100; 40 | 3'b011 : y = 8'b00001000; 41 | 3'b100 : y = 8'b00010000; 42 | 3'b101 : y = 8'b00100000; 43 | 3'b110 : y = 8'b01000000; 44 | 3'b111 : y = 8'b10000000; 45 | default : y = 8'b00000000; 46 | endcase 47 | end 48 | end 49 | 50 | endmodule 51 | 52 | -------------------------------------------------------------------------------- /src/led_clk.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: led_clk.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.0 10 | * Rev. Date: November 5, 2016 11 | * 12 | * Purpose: The purpose of this module is to divide the 100MHz board clock 13 | to a 480Hz clock for refreshing the 7-segment displays. This is clocks 14 | purpose is to assert one anode at a time at a proper frequency to make 15 | it seem as though all of the 7-segment displays are on at the same time. 16 | * 17 | * Notes: Nexys 4 has a "8x1" display; 8 pixels in total. Since our desired 18 | refresh frequency is 60Hz(60 times per second) we will have to refresh 19 | 60*8 pixels every second. This is how the 480 pixel clock was calculated. 20 | * 21 | ****************************************************************************/ 22 | 23 | `timescale 1ns / 1ps 24 | 25 | module led_clk( clk_in, reset, clk_out ); 26 | 27 | input clk_in, reset; 28 | output reg clk_out; 29 | integer i; 30 | //*************************************************************** 31 | // The following verilog code will "divide" an incoming clock 32 | // by the 32-bit decimal value specified in the "if condition" 33 | // 34 | // The value of the timer that counts the incoming clock ticks 35 | // is equal to [ (Incoming Freq / Outgoing Freq) / 2 ] 36 | //*************************************************************** 37 | 38 | always @( posedge clk_in or posedge reset) begin 39 | if ( reset == 1 ) begin 40 | clk_out = 0; 41 | i = 0; 42 | end else begin 43 | i = i+1; 44 | if ( i >= ((100000000/480)/2)) begin 45 | clk_out = ~clk_out; 46 | i = 0; 47 | end //if 48 | end //else 49 | end // always 50 | 51 | endmodule 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/led_controller.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: led_controller.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.0 10 | * Rev. Date: November 5, 2016 11 | * 12 | * Purpose: The purpose of this module is to drive the basic concept of 13 | displays: selecting one pixel at a time and sending that pixel its 14 | corresponding pixel "data". This is achieved in this project using 15 | two modules: (1) This led controller module & (2) an 8 to 1 multiplexer. 16 | This module is an autonomous finite state machine which changes state 17 | every positive edge of the clock and outputs a 3-bit select value 18 | and asserts one anode at avery state. 19 | * 20 | * Notes: 21 | * 22 | ****************************************************************************/ 23 | 24 | `timescale 1ns / 1ps 25 | 26 | module led_controller( clk, reset, an, seg_sel ); 27 | 28 | input clk, reset; 29 | output reg [7:0] an; 30 | output reg [2:0] seg_sel; 31 | 32 | reg [2:0] present_state; 33 | reg [2:0] next_state; 34 | 35 | //=================================================== 36 | // Next State Combinational Logic 37 | //=================================================== 38 | always @(present_state) 39 | begin 40 | case (present_state) 41 | 3'b000 : next_state = 3'b001; 42 | 3'b001 : next_state = 3'b010; 43 | 3'b010 : next_state = 3'b011; 44 | 3'b011 : next_state = 3'b100; 45 | 3'b100 : next_state = 3'b101; 46 | 3'b101 : next_state = 3'b110; 47 | 3'b110 : next_state = 3'b111; 48 | 3'b111 : next_state = 3'b000; 49 | default : next_state = 3'b000; 50 | endcase 51 | end 52 | 53 | //=================================================== 54 | // State Register Logic (Sequential Logic) 55 | //=================================================== 56 | always @(posedge clk or posedge reset) 57 | begin 58 | if (reset == 1'b1) 59 | present_state = 3'b000; 60 | else 61 | present_state = next_state; 62 | end 63 | 64 | //=================================================== 65 | // Output Combinational Logic 66 | //=================================================== 67 | always @(present_state) 68 | begin 69 | case (present_state) 70 | 3'b000 : {seg_sel, an} = 11'b000_11111110; 71 | 3'b001 : {seg_sel, an} = 11'b001_11111101; 72 | 3'b010 : {seg_sel, an} = 11'b010_11111011; 73 | 3'b011 : {seg_sel, an} = 11'b011_11110111; 74 | 3'b100 : {seg_sel, an} = 11'b100_11101111; 75 | 3'b101 : {seg_sel, an} = 11'b101_11011111; 76 | 3'b110 : {seg_sel, an} = 11'b110_10111111; 77 | 3'b111 : {seg_sel, an} = 11'b111_01111111; 78 | default : {seg_sel, an} = 11'b000_11111110; 79 | endcase 80 | end 81 | 82 | endmodule 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /src/mux_8_to_1.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: mux_8_to_1.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.0 10 | * Rev. Date: November 5, 2016 11 | * 12 | * Purpose: This module represents an 8 to 1 multiplexer that is in charge 13 | of selecting what data will be sent to the Hex to 7 segment decoder. In 14 | specific terms, the data stored in the ram will be selected by the select 15 | signal that was received from the led controller module. 16 | * 17 | * Notes: The module was written using behavioral verilog which uses an 18 | always block and a case statement. The always block is sensetive to the 19 | the inputs and select. The case statement is used to assain an output 20 | according to select's value. 21 | * 22 | ****************************************************************************/ 23 | 24 | `timescale 1ns / 1ps 25 | 26 | module mux_8_to_1( d0, d1, d2, d3, d4, d5, d6, d7, sel, Y ); 27 | 28 | input [2:0] sel; 29 | input [3:0] d0; 30 | input [3:0] d1; 31 | input [3:0] d2; 32 | input [3:0] d3; 33 | input [3:0] d4; 34 | input [3:0] d5; 35 | input [3:0] d6; 36 | input [3:0] d7; 37 | output reg [3:0] Y; 38 | 39 | always @(sel, d0,d1,d2,d3,d4,d5,d6,d7) 40 | begin 41 | case (sel) 42 | 3'b000 : Y = d0; 43 | 3'b001 : Y = d1; 44 | 3'b010 : Y = d2; 45 | 3'b011 : Y = d3; 46 | 3'b100 : Y = d4; 47 | 3'b101 : Y = d5; 48 | 3'b110 : Y = d6; 49 | 3'b111 : Y = d7; 50 | default : Y = 4'b1111; 51 | endcase //ends case statement 52 | end //ends always statement 53 | 54 | endmodule 55 | 56 | -------------------------------------------------------------------------------- /src/ram1.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: ram1.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.1 10 | * Rev. Date: November 28, 2016 11 | * 12 | * Purpose: 13 | * 14 | * Notes: ram is loaded with 8A COE-file. 15 | * 16 | ****************************************************************************/ 17 | `timescale 1ns / 1ps 18 | 19 | module ram1( clk , we, addr, din, dout ); 20 | 21 | input clk, we; 22 | input [15:0] addr; 23 | input [15:0] din; 24 | output [15:0] dout; 25 | 26 | //----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG 27 | ram_256x16 ram ( 28 | .clka(clk), // input clka 29 | .wea(we), // input [0 : 0] wea 30 | .addra(addr), // input [7 : 0] addra 31 | .dina(din), // input [15 : 0] dina 32 | .douta(dout) // output [15 : 0] douta 33 | ); 34 | // INST_TAG_END ------ End INSTANTIATION Template --------- 35 | 36 | endmodule 37 | 38 | -------------------------------------------------------------------------------- /src/reg16.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: reg16.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.0 10 | * Rev. Date: October 13, 2016 11 | * 12 | * Purpose: This module represents a 16-bit register with an asynchronous 13 | reset and a synchronous load for the Din input. Just like we know, a 14 | register is made up of an array of flip flops, therefore this 16 bit 15 | register will be used to store information in this case it to store 16 bits. 16 | * 17 | * Notes: It is written in behavioral verilog and it will only operate on the 18 | positive edge of the clock or when the reset button in pressed. If the reset 19 | is pressed the register will make Dout equal to 16'b0 or else if load is used 20 | than it will output the Din or else it will ouput the Dout. We also used an 21 | assign statement for reading the register. 22 | * 23 | ****************************************************************************/ 24 | `timescale 1ns / 1ps 25 | 26 | module reg16( clk, reset, ld, Din, DA, DB, oeA, oeB ); 27 | 28 | input clk, reset, ld, oeA, oeB; 29 | input [15:0] Din; 30 | output [15:0] DA, DB; 31 | reg [15:0] Dout; 32 | 33 | // Behavioral section for writing to the register 34 | always @ ( posedge clk or posedge reset ) 35 | if (reset) 36 | Dout <= 16'b0; 37 | else 38 | if (ld) 39 | Dout <= Din; 40 | else Dout <= Dout; 41 | 42 | // Conditional continuous assignments for reading the register 43 | assign DA = oeA ? Dout : 16'hz; 44 | assign DB = oeB ? Dout : 16'hz; 45 | 46 | endmodule 47 | 48 | -------------------------------------------------------------------------------- /src/risc_top.v: -------------------------------------------------------------------------------- 1 | /****************************** C E C S 3 0 1 ****************************** 2 | * 3 | * File Name: risc_top.v 4 | * Project: Lab Project 8: 16-Bit RISC Processor 5 | * Designer 1: Michael Rios 6 | * Email: riosmichael28@ymail.com 7 | * Designer 2: Yuliana Uriostegui 8 | * Email: yulove613@gmail.com 9 | * Rev. No.: Version 1.1 10 | * Rev. Date: November 28, 2016 11 | * 12 | * Purpose: This is the top level module to the RISC Processor Project. 13 | The purpose of this module is to interconnect all of the modules that make 14 | up the RISC project. Also, this module is responsible for mapping the control 15 | words which will connect to the I/O ports on the Nexys 4 board. 16 | * 17 | * Notes: Three bit files will be created from this top level module w/ only 18 | the init file of the Ram Module changing. 19 | * 20 | ****************************************************************************/ 21 | `timescale 1ns / 1ps 22 | 23 | module risc_top( clk, reset, step_clk, step_mem, dump_mem, 24 | led, an, a , b, c, d, e, f, g ); 25 | 26 | input clk, reset; 27 | input step_clk, step_mem; 28 | input dump_mem; 29 | output [7:0] led; 30 | output [7:0] an; 31 | output a, b, c, d, e, f, g; 32 | 33 | //wires: 34 | wire clk_500Hz, db_step_clk, db_step_mem; 35 | wire [15:0] D_out, Address, D_in; 36 | wire [15:0] mem_dump_out, mem_address; 37 | wire mw_en; 38 | 39 | // The line below instantiates the 500Hz clock divider. The input will 40 | // come from the 100MHz board clock of the Nexys 4DDR, and reset will be 41 | // controlled by the btn_up of the board. The output will be the divided 42 | // 500Hz clock that will be used for out debounce module. 43 | clk_500_Hz u0 ( .clk_in(clk), .reset(reset), .clk_out(clk_500Hz)); 44 | 45 | // The lines below instantiate the first debounce module which will debounce 46 | // the btn_dn of the Nexys 4DDR board. This button will be used to step the 47 | // clock forward. 48 | debounce u1 ( .clk_in(clk_500Hz), .reset(reset), .D_in(step_clk), 49 | .D_out(db_step_clk)); 50 | 51 | // The lines below instantiate the second debounce module which will be used 52 | // to debounce the left button of our Nexys 4DDR. This button will be used to 53 | // step through memory. 54 | debounce u2 ( .clk_in(clk_500Hz), .reset(reset), .D_in(step_mem), 55 | .D_out(db_step_mem)); 56 | 57 | // The code block below instantiates our RISC Processor module. This module 58 | // is made up by a control unit, and our CPU. Modifications were made to 59 | // the CPU in order to be able to execute jump instructions. 60 | RISC_Processor u3 ( .clk(db_step_clk), .reset(reset), 61 | .D_out(D_out), .Address(Address), .D_in(D_in), 62 | .mw_en(mw_en), .status(led)); 63 | 64 | // The lines below instantiate the 256x16 memory. The address input will come 65 | // from the CPU_EU module's output address. 66 | ram1 u4 ( .clk(clk), .we(mw_en), 67 | .addr(mem_address), .din(D_out), .dout(D_in)); 68 | 69 | // This line below instantiates then Memory dump counter. A 16-bit up-counter. 70 | MemDumpCounter u5 ( .clk(db_step_mem), .reset(reset), .addr(mem_dump_out)); 71 | 72 | // The code block below instantiates the display controller module which will dispay 73 | // 'Address' output of the CPU_EU in the first four segments and the 'D_in input to 74 | // the CPU_EU in the next four segments. 75 | Display_Controller u6( .clk(clk), .reset(reset), 76 | .seg0(mem_address[3:0]), .seg1(mem_address[7:4]), 77 | .seg2(mem_address[11:8]), .seg3(mem_address[15:12]), 78 | .seg4(D_in[3:0]), .seg5(D_in[7:4]), 79 | .seg6(D_in[11:8]), .seg7(D_in[15:12]), 80 | .an(an), .a(a), .b(b), .c(c), .d(d), .e(e), .f(f), .g(g)); 81 | 82 | // Assign statement represents a 2-to-1 multiplexer. 83 | // will choose which address location is chosen based on the dump_mem switch. 84 | assign mem_address = (dump_mem) ? mem_dump_out : Address; 85 | 86 | endmodule 87 | 88 | 89 | 90 | --------------------------------------------------------------------------------