OpenCores
URL https://opencores.org/ocsvn/edge/edge/trunk

Subversion Repositories edge

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/edge/trunk/DOC/EdgeDiagram.png Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
edge/trunk/DOC/EdgeDiagram.png Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: edge/trunk/SW/Apps/ledsOut.c =================================================================== --- edge/trunk/SW/Apps/ledsOut.c (nonexistent) +++ edge/trunk/SW/Apps/ledsOut.c (revision 2) @@ -0,0 +1,10 @@ +#include "Edge_Atlys_LEDS.h" + +void main() +{ + int i = 0; + + for(i=0; i<=10; i++) + led_8b_send((char) i); + +} Index: edge/trunk/SW/Apps/include/uart.h =================================================================== --- edge/trunk/SW/Apps/include/uart.h (nonexistent) +++ edge/trunk/SW/Apps/include/uart.h (revision 2) @@ -0,0 +1,4 @@ +#define UART_REG_BYTE 0xFFFF0100 +#define UART_REG_CTRL 0xFFFF0104 + +void uart_send_byte(char byte); Index: edge/trunk/SW/Apps/include/stdio.h =================================================================== --- edge/trunk/SW/Apps/include/stdio.h (nonexistent) +++ edge/trunk/SW/Apps/include/stdio.h (revision 2) @@ -0,0 +1,2 @@ +void printf(char *); +void putc(char ); Index: edge/trunk/SW/Apps/include/Edge_Atlys_LEDS.h =================================================================== --- edge/trunk/SW/Apps/include/Edge_Atlys_LEDS.h (nonexistent) +++ edge/trunk/SW/Apps/include/Edge_Atlys_LEDS.h (revision 2) @@ -0,0 +1,3 @@ +#define UART_REG_LED 0xFFFF0108 + +void led_8b_send(char pattern); Index: edge/trunk/SW/Apps/stdio.c =================================================================== --- edge/trunk/SW/Apps/stdio.c (nonexistent) +++ edge/trunk/SW/Apps/stdio.c (revision 2) @@ -0,0 +1,26 @@ +#include "stdio.h" +#include "uart.h" + +void putc(char c) +{ + uart_send_byte(c); +} + +void printf(char *string) +{ + int i; + for (i=0; string[i] != '\0'; i++) + { + putc(string[i]); + } +} + +void printInt(int num) +{ + int i = 0; + // print first 3 digits. + putc(((num%1000)/100) + 48); + putc(((num % 100)/10) + 48); + putc((num % 10) + 48); + +} Index: edge/trunk/SW/Apps/edge.linkcmd =================================================================== --- edge/trunk/SW/Apps/edge.linkcmd (nonexistent) +++ edge/trunk/SW/Apps/edge.linkcmd (revision 2) @@ -0,0 +1,19 @@ +MEMORY +{ + text (rx) : ORIGIN = 0, LENGTH = 2K + rodata (r) : ORIGIN = 0x00000800, LENGTH = 1K +} + +SECTIONS +{ + . = 0x00000000; + .text ALIGN(0x04): + { *(.text) } > text + .rodata : { *(.rodata) } > rodata + + .data : { *(.data) } + + .bss : { *(.bss) } +} + + Index: edge/trunk/SW/Apps/Edge_Atlys_LEDS.c =================================================================== --- edge/trunk/SW/Apps/Edge_Atlys_LEDS.c (nonexistent) +++ edge/trunk/SW/Apps/Edge_Atlys_LEDS.c (revision 2) @@ -0,0 +1,6 @@ +#include "Edge_Atlys_LEDS.h" + +void led_8b_send(char pattern) +{ + *((char *)UART_REG_LED) = pattern; +} Index: edge/trunk/SW/Apps/ledsOutWithDelay.c =================================================================== --- edge/trunk/SW/Apps/ledsOutWithDelay.c (nonexistent) +++ edge/trunk/SW/Apps/ledsOutWithDelay.c (revision 2) @@ -0,0 +1,14 @@ +#include "Edge_Atlys_LEDS.h" + +void main() +{ + int i; + int x = 1; + + for(i=0; i<=10; i++) + { + led_8b_send((char) x << i); + fsleep(1000); + } + +} Index: edge/trunk/SW/Apps/start.asm =================================================================== --- edge/trunk/SW/Apps/start.asm (nonexistent) +++ edge/trunk/SW/Apps/start.asm (revision 2) @@ -0,0 +1,34 @@ +.text + .align 2 + .global entry + .ent entry +entry: + .set noreorder + la $sp, 1000 + jal main + nop +$L1: + j $L1 + + .end entry + + .global fsleep + .ent fsleep +fsleep: + .set noreorder + + mtc0 $a0, $11 + mtc0 $zero, $9 + lui $k0, 0xffff + ori $k0, 0x010c + lw $k1, 0($k0) + andi $k1,$k1,0x1 + beqz $k1,fsleep + 16 + sw $zero, 0($k0) + nop + nop + nop + jr $ra + + .set reorder + .end fsleep Index: edge/trunk/SW/Apps/helloWorld.c =================================================================== --- edge/trunk/SW/Apps/helloWorld.c (nonexistent) +++ edge/trunk/SW/Apps/helloWorld.c (revision 2) @@ -0,0 +1,8 @@ +#include "stdio.h" + +void main() +{ + printf("Hello World from Edge Microprocessor. \n\r\ +This is a trial C program. Congratulations, the processor \n\r\ +is normally working as you see this message.\n\rThanks for trying Edge !\r\n"); +} Index: edge/trunk/SW/Apps/uart.c =================================================================== --- edge/trunk/SW/Apps/uart.c (nonexistent) +++ edge/trunk/SW/Apps/uart.c (revision 2) @@ -0,0 +1,20 @@ +#include "uart.h" + +void uart_send_byte(char byte) +{ + char *uart_byte_reg = UART_REG_BYTE; + char *uart_byte_ctrl = UART_REG_CTRL; + + char isReady; + + for( ; ; ) + { + isReady = *uart_byte_ctrl & 0x1; + if(isReady) + { + *uart_byte_reg = byte; + break; + } + } + +} Index: edge/trunk/SW/Apps/Makefile =================================================================== --- edge/trunk/SW/Apps/Makefile (nonexistent) +++ edge/trunk/SW/Apps/Makefile (revision 2) @@ -0,0 +1,31 @@ +GCC_MIPS = mips-linux-gnu-gcc $(CFLAGS) +AS_MIPS = mips-linux-gnu-as +LD_MIPS = mips-linux-gnu-ld +INCLUDE = -Iinclude/ +RM = rm -rf +CP = cp + +CFLAGS = -O0 -EB -Wall -c -s -fno-pic -mips1 -mno-check-zero-division -mdivide-traps -mno-abicalls $(INCLUDE) + +hello: + @echo "................ Compiling Hello Source Code ......................" + $(AS_MIPS) -EB -o start.o start.asm + $(GCC_MIPS) -EB helloWorld.c uart.c stdio.c + $(LD_MIPS) -EB -T edge.linkcmd start.o helloWorld.o uart.o stdio.o -o helloWorld.elf + +leds: + @echo "................ Compiling leds Source Code ......................" + $(AS_MIPS) -EB -o start.o start.asm + $(GCC_MIPS) -EB ledsOutWithDelay.c Edge_Atlys_LEDS.c + $(LD_MIPS) -EB -T edge.linkcmd start.o Edge_Atlys_LEDS.o ledsOutWithDelay.o -o ledsDelay.elf + +hello_atlys: hello + @echo "................ Programming bit file ......................" + data2mem -bt ../../HW/Boards/Atlys/edge_atlys.bit -bd helloWorld.elf -bm ../../HW/Boards/Atlys/EdgeMemMap.bmm -o b edge_processor.bit + +leds_atlys: leds + @echo "................ Programming bit file ......................" + data2mem -bt ../../HW/Boards/Atlys/edge_atlys.bit -bd ledsDelay.elf -bm ../../HW/Boards/Atlys/EdgeMemMap.bmm -o b edge_processor.bit + +clean: + -$(RM) *.o *.elf *.bit *~ *.log *.cmd Index: edge/trunk/HW/Verilog/edge_core.v =================================================================== --- edge/trunk/HW/Verilog/edge_core.v (nonexistent) +++ edge/trunk/HW/Verilog/edge_core.v (revision 2) @@ -0,0 +1,1077 @@ +////////////////////////////////////////////////////////////////// +// // +// Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// The main top module for Edge core. It contains the whole // +// data path and pipeline stuff. +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +`define BLTZ_OPCODE 6'b000001 // 1 +`define BGEZ_OPCODE 6'b000001 // 1 +`define JMP_OPCODE 6'b000010 // 2 +`define JAL_OPCODE 6'b000011 // 3 +`define BEQ_OPCODE 6'b000100 // 4 +`define BNE_OPCODE 6'b000101 // 5 +`define BLEZ_OPCODE 6'b000110 // 6 +`define BGTZ_OPCODE 6'b000111 // 7 + +module Edge_Core +# +( + parameter N=32, M=5 +) +( + input clk, + input reset, + + /* Instruction Memory */ + output[N-1:0] pc_toIMemory, + input[N-1:0] instr_fromIMemory, + + /* Data Memory */ + output[N-1:0] Address_toDMemory, + output[N-1:0] WriteData_toDMemory, + output MemWrite_toDMemory, /* Write Enable signal to data memory */ + input[N-1:0] RD_fromDMemory, /* Data rereived from data memory */ + output[1:0] MemRefSize, /* Zero Byte, Half word, or Word reference */ + input StallDataMemory, // Stall signal from data memory (Technology dependent) + + /* Interrupts */ + output CP0_TimerIntMatch, + input IO_TimerIntReset +); + + +/******************************* PC Wires ************************************** +* +* +* +*******************************************************************************/ +wire pc_en; +wire PC_STALL_HAZARD; +wire[N-1:0] pc_current; +wire[N-1:0] pc_next; +wire[2:0] PCSrcM; /* PC src signal (from PCplus4 or from branch) */ +wire PC_RESET; +wire PC_RESET_HAZARD; + +/******************************* IF/ID Wires *********************************** +* +* +* +*******************************************************************************/ +wire IF_ID_EN; +wire IF_ID_EN_GLOBAL; +wire IF_ID_STALL_HAZARD; + +wire IF_ID_RESET; /* Final reset value */ +wire IF_ID_RESET_GLOBAL; /* Blobal reset from the processor */ +wire IF_ID_RESET_HAZARD; /* Reset due to hazard unit (flush) */ +wire IF_ID_RESET_INT; /* Reset due to interrupt taken */ +reg IF_ID_RESET_FINAL; + +wire[N-1:0] IR_in; +wire[N-1:0] IR_out; +wire[N-1:0] PCplus4F; + +/* Coprocessor0 and exceptions signals */ +wire undefinedExD; +wire breakExD; +wire divbyZeroExD; +wire syscallExD; + +wire[M-1:0] CP0_waD; +wire[M-1:0] CP0_raD; +wire[1:0] CP0_InstD; +wire[N-1:0] CP0_doutD; +wire[N-1:0] CP0_dinD; +wire mfc0D; /* Signal to MUX to choose register value from Coprocessor 0 */ +wire[M-1:0] ra1D; +wire[1:0] MemRefSizeD; + +/******************************** ID/EX Wires ********************************** +* +* +*******************************************************************************/ +wire ID_EX_EN; +wire ID_EX_RESET; +wire ID_EX_RESET_GLOBAL; +wire ID_EX_RESET_HAZARD; +wire ID_EX_RESET_INT; +wire ID_EX_RESET_FINAL; +wire ID_EX_STALL_HAZARD; +wire[M-1:0] read_reg1_in; +wire[M-1:0] read_reg2_in; +wire[M-1:0] write_reg1_in; +wire[N-1:0] read_value1_in; +wire[N-1:0] read_value2_in; +wire[M-1:0] Rt_in; +wire[M-1:0] Rd_in; +wire[N-1:0] SignImm_in; +wire[N-1:0] PCplus4D; +wire linkD; + +wire RegWriteD; +wire[1:0] WBResultSelectD; +wire MemWriteD; +wire BranchD; +wire JumpD; +wire JumpRD; +wire[3:0] ALUControlD; +wire ALUSrcBD; +wire RegDstD; +wire ALUCompD; +wire[1:0] Shift_typeD; +wire ShiftAmtVarD; +wire Shifter_or_ALUD; +wire[1:0] MulDivRFD; /* Control Signal input to mux to choose between mul, div, +rf wires */ +wire hiEND, loEND; /* Enable load signal for lo and hi registers */ +wire [5:0] opcodeD; +wire[N-1:0] IR_D; +wire[N-1:0] PC_D; +wire isExW; +wire[N-1:0] rd2D; /* input of value2 to ID/EX register */ +wire[M-1:0] read_reg1_out; +wire[M-1:0] read_reg2_out; +wire[M-1:0] write_reg1_out; +wire[N-1:0] read_value1_out; +wire[N-1:0] read_value2_out; +wire[M-1:0] Rs_out; +wire[M-1:0] Rt_out; +wire[M-1:0] Rd_out; +wire[N-1:0] SignImm_out; + +/******************************* EX/MEM Wires ********************************** +* +* +*******************************************************************************/ +wire EX_MEM_EN; +wire EX_MEM_RESET; +wire EX_MEM_RESET_GLOBAL; +wire EX_MEM_RESET_INT; +wire EX_MEM_STALL_HAZARD; +wire[N-1:0] ALUoutE; +wire[N-1:0] PCBranchE; +wire[M-1:0] WriteRegE; + +wire RegWriteE; +wire[1:0] WBResultSelectE; +wire MemWriteE; +wire BranchE; +wire JumpE; +wire JumpRE; +wire[3:0] ALUControlE; +wire ALUSrcBE; +wire RegDstE; +wire[N-1:0] SrcAE; +wire[N-1:0] SrcBE; +wire[N-1:0] IR_E; +wire[1:0] ForwardAE, ForwardBE; /* Forward signals coming from hazard unit */ +wire[N-1:0] mux_ForwardDataAE, mux_ForwardDataBE; +wire[N-1:0] ALUoutEE; +wire UpperImmD; +wire UpperImmE; +wire ALUCompE; +wire[1:0] Shift_typeE; +wire ShiftAmtVarE; +wire Shifter_or_ALUE; +wire[N-1:0] Shift_ResultE; +wire[N-1:0] EX_Result; +wire[1:0] MulDivRFE; /* Control Signal input to mux to choose between mul, div, +rf wires */ +wire hiENE, loENE; /* Enable load signal for lo and hi registers */ +wire [5:0] opcodeE; +wire [N-1:0] JTA_E; /* Jump target address */ +wire linkE; +wire[N-1:0] PCplus4E; +wire[1:0] MemRefSizeE; +wire zeroE; +wire SignE; + +/* Coprocessor0 and exceptions signals */ +wire undefinedExE; +wire breakExE; +wire divbyZeroExE; +wire syscallExE; + +wire[M-1:0] CP0_waE; +wire[M-1:0] CP0_raE; +wire[1:0] CP0_InstE; +wire[N-1:0] CP0_doutE; +wire[N-1:0] CP0_dinE; + +wire[N-1:0] shifted_imm_2; +wire[N-1:0] ALUoutCompE; +wire[4:0] ShiftAmtE; + +/* Output wires from Mul/Div units */ +wire[N-1:0] hiIn, loIn, hiE, loE; +wire[N-1:0] hiMulE, loMulE, hiDivE, loDivE; + +/********************************** MEM/WB Wires ******************************* +* +* +*******************************************************************************/ + +wire zeroM; +wire SignM; + +wire[N-1:0] ALUoutM; +wire[N-1:0] WriteDataM; +wire[N-1:0] PCBranchM; +wire[M-1:0] WriteRegM; +wire RegWriteM; +wire[1:0] WBResultSelectM; +wire MemWriteM; +wire BranchM; +wire JumpM; +wire JumpRM; +wire[N-1:0] ReadDataM; +wire[N-1:0] hiM, loM; +wire [5:0] opcodeM; +wire [N-1:0] JTA_M; /* Jump target address */ +wire[N-1:0] PCplus4M; +wire linkM; + +/* Coprocessor0 and exceptions signals */ +wire undefinedExM; +wire breakExM; +wire divbyZeroM; +wire syscallExM; + +wire[M-1:0] CP0_waM; +wire[M-1:0] CP0_raM; +wire[1:0] CP0_InstM; +wire[N-1:0] CP0_doutM; +wire[N-1:0] CP0_dinM; + +wire[1:0] MemRefSizeM; + +/****************************** WB Wires *************************************** +* +* +*******************************************************************************/ +wire MEM_WB_EN; +wire MEM_WB_STALL_HAZARD; +wire[N-1:0] ReadDataW; +wire[N-1:0] ALUoutW; +wire[M-1:0] WriteRegW; +wire RegWriteW; +wire[1:0] WBResultSelectW; +wire[N-1:0] hiW, loW; +wire[N-1:0] PCplus4W; +wire[N-1:0] ResultW; /* Result to be written in RF */ +wire linkW; +wire[N-1:0] ResultWWW; +wire[M-1:0] WriteRegWW; + +/* Coprocessor0 and exceptions signals */ +wire undefinedExW; +wire breakExW; +wire divbyZeroExW; +wire syscallExW; + +wire[M-1:0] CP0_waW; +wire[M-1:0] CP0_raW; +wire[1:0] CP0_InstW; +wire[N-1:0] CP0_doutW; +wire[N-1:0] CP0_dinW; +wire[N-1:0] ImmSigned, ImmUSigned; +wire ImmSorU; + +/* output of the 3-way mux (lw, lb, lh) */ +wire[N-1:0] ResultWW, ResultSHW, ResultSB, ResultUHW, ResultUB; +/* Selection bits for ResultWW mux (comes from decoder) */ +wire[2:0] bhwD, bhwE, bhwM, bhwW; + +/****************************** Coprocessor0 Wires ***************************** +* +* +*******************************************************************************/ +wire[1:0] CP0_Inst; +wire[N-1:0] CP0_Cause; +wire[N-1:0] CP0_EPC; +wire[M-1:0] CP0_wa, CP0_ra; +wire[N-1:0] CP0_wd; +wire[N-1:0] CP0_rd; +wire[N-1:0] PC_W; +wire CP0_TimerIntMatch; + +/****************************** Data path ************************************** +* +* +*******************************************************************************/ + +/* Hazard Control Unit */ +hazard_unit hazard_unit +( + .CLK(clk), + .rsE(Rs_out), .rtE(Rt_out), + .rsD(IR_out[25:21]), .rtD(IR_out[20:16]), + .DestRegE(WriteRegE), + .DestRegM(WriteRegM), .DestRegW(WriteRegWW), + .RegWriteE(RegWriteE), + .RegWriteM(RegWriteM), .RegWriteW(RegWriteW), + .loadE((WBResultSelectE)== 2'b01), + .PCSrcM(PCSrcM), + .MemWriteD(MemWriteD), + .MemWriteE(MemWriteE), + .StallF(PC_STALL_HAZARD), + .StallD(IF_ID_STALL_HAZARD), + .StallE(ID_EX_STALL_HAZARD), + .StallM(EX_MEM_STALL_HAZARD), + .StallW(MEM_WB_STALL_HAZARD), + .FlushF(PC_RESET_HAZARD), + .FlushD(IF_ID_RESET_HAZARD), + .FlushE(ID_EX_RESET_HAZARD), + .FlushM(EX_MEM_RESET_HAZARD), + .ForwardAE(ForwardAE), + .ForwardBE(ForwardBE), + .StallDataMemory(StallDataMemory) +); + + +assign pc_en = (PCSrcM == 3'b000)? + ((~PC_STALL_HAZARD) & (~StallDataMemory)) + : + 1'b1 ; + +assign IF_ID_RESET_GLOBAL = reset; +assign IF_ID_RESET_INT = 1'b0; + +assign ID_EX_RESET_GLOBAL = reset; +assign ID_EX_RESET_INT = 1'b0; + +assign EX_MEM_RESET_GLOBAL = reset; +assign EX_MEM_RESET_INT = 1'b0; + +assign IF_ID_EN = (~IF_ID_STALL_HAZARD) & (~StallDataMemory); +assign ID_EX_EN = (~ID_EX_STALL_HAZARD) & (~StallDataMemory); +assign EX_MEM_EN = /*(~EX_MEM_STALL_HAZARD) &*/ (~StallDataMemory); +assign MEM_WB_EN = /*(~MEM_WB_STALL_HAZARD)*/ 1'b1; + +assign PC_RESET = (reset); +assign IF_ID_RESET = + (IF_ID_RESET_GLOBAL | + IF_ID_RESET_HAZARD | + IF_ID_RESET_INT + ) ? + 1'b1 + : + 1'b0; + +assign ID_EX_RESET = + (ID_EX_RESET_GLOBAL | + ID_EX_RESET_HAZARD | + ID_EX_RESET_INT + ) ? + 1'b1 + : + 1'b0; + +assign EX_MEM_RESET = + (EX_MEM_RESET_GLOBAL | + EX_MEM_RESET_HAZARD | + EX_MEM_RESET_INT + ) ? + 1'b1 + : + 1'b0; + +assign MemRefSize = MemRefSizeM; + +assign PC_W = PCplus4W - 4; + +/* Excepetion detection and CP0 interaction */ + +assign isExW = + (undefinedExW || + breakExW || + divbyZeroExW || + syscallExW + ) ? + 1'b1 + : + 1'b0; + +assign CP0_Cause = + (undefinedExW) ? + 32'h00000028 + : + (breakExW | divbyZeroExW)? + 32'h00000024 + : + (syscallExW) ? + 32'h00000020 + : + 32'h00000000; + +assign CP0_EPC = PC_W; + +assign CP0_Inst = (isExW)? 2'd1 : CP0_InstW; + +assign CP0_ra = IR_out[15:11]; + +assign CP0_waD = IR_out[15:11]; + +assign CP0_wa = CP0_waW; + +assign CP0_InstD = (mtc0D)? 2'd3 : 2'd0; + +assign CP0_din = CP0_dinW; + +assign CP0_dinW = ResultWWW; + +/* Coprocessor 0 */ +Coprocessor0 cp0 +( + .clk(clk), + .EPC(CP0_EPC), + .Cause(CP0_Cause), + .instruction(CP0_Inst), + .ra(CP0_ra), + .wa(CP0_wa), + .WriteData(CP0_dinW), + .IO_TimerIntReset(IO_TimerIntReset), + .ReadData(CP0_rd), + .TimerIntMatch(CP0_TimerIntMatch) +); + +/* Mux signal to determine PC source at from memory pipleline stage */ +assign PCSrcM = + ((BranchM == 1'b0 && JumpM == 1'b0 && JumpRM == 1'b0)? + ((isExW)? 3'b100 : 3'b000) /* Check for excpetions */ + : /* not a branch or jump */ + ((JumpM) ? + /* Jump type */ + 3'b010 + : + ((JumpRM) ? + /* Jump Register */ + 3'b011 + : + ((BranchM) ? + /* Branch type */ + ((opcodeM == `BLTZ_OPCODE && SignM)? + ((Rt_out == 5'd0)? 3'b001 : 3'b000) : + (opcodeE == `BGEZ_OPCODE && SignM == 1'b0)? + ((Rt_out == 5'd1)? 3'b001 : 3'b000) : + (opcodeM == `BEQ_OPCODE && zeroM)? 3'b001 : + (opcodeM == `BNE_OPCODE && zeroM == 1'b0)? 3'b001 : + (opcodeM == `BLEZ_OPCODE && (SignM == 1 || zeroM == 0))? 3'b001 : + (opcodeM == `BGTZ_OPCODE && SignM == 0 && zeroM == 0)? 3'b001 : + 3'b000) + :3'b000)))); + +assign pc_next = + (reset == 1)? 32'd0 : + (PCSrcM === 0)? PCplus4F : + (PCSrcM === 1)? PCBranchM : + (PCSrcM === 2)? JTA_M : + (PCSrcM === 3)? ALUoutM : + (PCSrcM === 4)? 32'h80000180 : PCplus4F; + +assign pc_toIMemory = pc_current; + +/* PC + 4 adder at fetch pipeline stage */ +adder pcplus4 +( + .in1(pc_current), + .in2(32'd4), + .cin(1'b0), + .out(PCplus4F) +); + +/****************************** PC Register ************************************ +* +* +*******************************************************************************/ +register pc +( + .clk(clk), + .reset(PC_RESET), + .en(pc_en), + .d(pc_next), + .q(pc_current) +); + +/****************************** IF/ID Register ********************************* +* +* +*******************************************************************************/ +if_id_pipereg IF_ID_REG +( + .clk(clk), + .reset(IF_ID_RESET), + .en(IF_ID_EN), + .IR_in(instr_fromIMemory), + .IR_out(IR_out), + .PCplus4_in(PCplus4F), + .PCplus4_out(PCplus4D), + .PC_in(pc_current), + .PC_out(PC_D) +); + +/* Decode or controller */ +controller ctrl +( + .opcode(IR_out[31:26]), + .func(IR_out[5:0]), + .Instruction(IR_out), + + .RegWrite(RegWriteD), + .WBResultSelect(WBResultSelectD), + .MemWrite(MemWriteD), + .Branch(BranchD), + .Jump(JumpD), + .JumpR(JumpRD), + .ALUControl(ALUControlD), + .ALUSrcB(ALUSrcBD), + .RegDst(RegDstD), + .UpperImm_out(UpperImmD), + .BHW(bhwD), + .ImmSorU_out(ImmSorU), + .ALUComp_out(ALUCompD), + .ShiftAmtVar_out(ShiftAmtVarD), + .Shift_type_out(Shift_typeD), + .Shifter_or_ALU_out(Shifter_or_ALUD), + .MulDivRF(MulDivRFD), + .hiEN(hiEND), + .loEN(loEND), + .link(linkD), + .undefinedEx(undefinedExD), + .syscallEx(syscallExD), + .breakEx(breakExD), + .mfc0(mfc0D), + .mtc0(mtc0D), + .MemRefSize(MemRefSizeD) +); + +/* Check divide by Zero Exception */ +assign divbyZeroExD = + (IR_out[31:26] == 0 && + (IR_out[5:0] == 26 || IR_out[5:0] == 27) + ) ? + 1'b1 + : + 1'b0; + +/* mux to choose between lb, lh and lw signed extended */ +sign_extend #(32, 8) +s_extend_byte +( + .in(ResultW[7:0]), + .out(ResultSB) +); + +sign_extend #(32, 16) +s_extend_halfWord +( + .in(ResultW[15:0]), + .out(ResultSHW) +); + +/* zero extend for lbu, lhu */ +zero_extend #(32, 8) +z_extend_byte +( + .in(ResultW[7:0]), + .out(ResultUB) +); + +zero_extend #(32, 16) +z_extend_halfWord +( +.in(ResultW[15:0]), +.out(ResultUHW) +); + +/* bhw -> [S|U] byte or halfword or word */ +mux_WBResult WBResult +( + .Word(ResultW), + .SByte(ResultSB), + .SHWord(ResultSHW), + .UByte(ResultUB), + .UHWord(ResultUHW), + .s(bhwW), + .WBResult(ResultWW) +); + +assign WriteRegWW = (linkW)? 5'd31 : WriteRegW; +assign ResultWWW = (linkW)? PCplus4W : ResultWW; + +/* Workaroud for mtc0 instruction */ +assign ra1D = (mtc0D)? 5'd0 : IR_out[25:21]; + +/****** register file *********/ +regfile rf( + .clk(clk), + .reset(reset), + .ra1(ra1D), + .ra2(IR_out[20:16]), + .wa3(WriteRegWW), + .we3(RegWriteW), + .wd3(ResultWWW), + .rd1(read_value1_in), + .rd2(read_value2_in) +); + +sign_extend sign_ex_unit +( + .in(IR_out[15:0]), + .out(ImmSigned) +); + +zero_extend #(32, 16) +zero_ex_unit +( + .in(IR_out[15:0]), + .out(ImmUSigned) +); + +/* Choose signed or unsgined immediate */ +mux2 Imm_Signed_or_UnSgined +( + .in1(ImmSigned), + .in2(ImmUSigned), + .s(ImmSorU), + .out(SignImm_in) +); + +/* Choose value2 from rf or CP0 */ +assign rd2D = (mfc0D)? CP0_rd : read_value2_in; + +/****************************** ID/EX Register ********************************* +* +* +*******************************************************************************/ + +id_ex_pipereg ID_EX_REG +( + .clk(clk), + .reset(ID_EX_RESET), + .en(ID_EX_EN), + .IR_in(IR_out), + .opcode_in(IR_out[31:26]), + .read_value1_in(read_value1_in), + .read_value2_in(rd2D), + .Rs_in(IR_out[25:21]), + .Rt_in(IR_out[20:16]), + .Rd_in(IR_out[15:11]), + .SignImm_in(SignImm_in), + .PCplus4_in(PCplus4D), + .RegWrite_in(RegWriteD), + .WBResultSelect_in(WBResultSelectD), + .MemWrite_in(MemWriteD), + .Branch_in(BranchD), + .Jump_in(JumpD), + .JumpR_in(JumpRD), + .ALUControl_in(ALUControlD), + .ALUSrcB_in(ALUSrcBD), + .RegDst_in(RegDstD), + .UpperImm_in(UpperImmD), + .BHW_in(bhwD), + .ALUComp_in(ALUCompD), + .Shift_type_in(Shift_typeD), + .ShiftAmtVar_in(ShiftAmtVarD), + .Shifter_or_ALU_in(Shifter_or_ALUD), + .MulDivRF_in(MulDivRFD), + .hiEN_in(hiEND), + .loEN_in(loEND), + .link_in(linkD), + .undefinedEx_in(undefinedExD), + .breakEx_in(breakExD), + .divbyZero_in(divbyZeroExD), + .syscallEx_in(syscallExD), + .CP0_wa_in(CP0_waD), + .CP0_ra_in(CP0_raD), + .CP0_Inst_in(CP0_InstD), + .CP0_dout_in(CP0_doutD), + .CP0_din_in(CP0_dinD), + .MemRefSize_in(MemRefSizeD), + + .read_value1_out(read_value1_out), + .read_value2_out(read_value2_out), + .Rs_out(Rs_out), + .Rt_out(Rt_out), + .Rd_out(Rd_out), + .SignImm_out(SignImm_out), + .PCplus4_out(PCplus4E), + + .RegWrite_out(RegWriteE), + .WBResultSelect_out(WBResultSelectE), + .MemWrite_out(MemWriteE), + .Branch_out(BranchE), + .Jump_out(JumpE), + .JumpR_out(JumpRE), + .ALUControl_out(ALUControlE), + .ALUSrcB_out(ALUSrcBE), + .RegDst_out(RegDstE), + .UpperImm_out(UpperImmE), + .BHW_out(bhwE), + .ALUComp_out(ALUCompE), + .Shift_type_out(Shift_typeE), + .ShiftAmtVar_out(ShiftAmtVarE), + .Shifter_or_ALU_out(Shifter_or_ALUE), + .MulDivRF_out(MulDivRFE), + .hiEN_out(hiENE), + .loEN_out(loENE), + .opcode_out(opcodeE), + .IR_out(IR_E), + .link_out(linkE), + .undefinedEx_out(undefinedExE), + .breakEx_out(breakExE), + .divbyZero_out(divbyZeroExE), + .syscallEx_out(syscallExE), + .CP0_wa_out(CP0_waE), + .CP0_ra_out(CP0_raE), + .CP0_Inst_out(CP0_InstE), + .CP0_dout_out(CP0_doutE), + .CP0_din_out(CP0_dinE), + .MemRefSize_out(MemRefSizeE) +); + +/* MUX to choose register destination address */ +mux2 #(5) +Rt_or_Rd +( + .in1(Rt_out), + .in2(Rd_out), + .s(RegDstE), + .out(WriteRegE) +); + +/* Mux inputs : + > From registe r file + > Forwarded from memory stage + > Forwarded from WB stage + Mux outputs + > to ALU src A stage. +*/ +assign mux_ForwardDataAE = (ForwardAE == 2'b00) ? + /* No forwarding SrcB coming from reg file */ + (read_value1_out) /* ForwardAE True part */ + : /* Hazard Detected and Data should be fowarded. Else part of ForwardAE*/ + ( + (ForwardAE == 2'b01)? + ResultWWW /* Data forwarded from WB stage */ + : + (ForwardAE == 2'b10)? + ALUoutM /* Data forwarded from Memory stage */ + : + read_value1_out /* No forwarding : fill this to avoid generating a +latch*/ + ); + +/* Mux inputs : + > From register file + > Forwarded from memory stage + > Forwarded from WB stage + Mux output + > to ALU src B stage. +*/ +assign mux_ForwardDataBE = (ForwardBE == 2'b00) ? + /* No forwarding SrcB coming from reg file */ + (read_value2_out) /* ForwardAE True part */ + : /* Hazard Detected and Data should be fowarded. Else part of ForwardAE*/ + ( + (ForwardBE == 2'b01)? + ResultWWW /* Data forwarded from WB stage */ + : + (ForwardBE == 2'b10)? + ALUoutM /* Data forwarded from Memory stage */ + : + read_value2_out /* No forwarding : fill this to avoid generating a + latch*/ + ); + + +/* SrcB to ALU whether from mux_ForwardDataE or signImmediate */ +mux2 Rd2_or_SignImm +( + .in1(mux_ForwardDataBE), + .in2(SignImm_out), + .s(ALUSrcBE), + .out(SrcBE) +); + +/* Multiplication unit */ +mult_unit mult_unit +( + .a(mux_ForwardDataAE), + .b(SrcBE), + .hi(hiMulE), + .lo(loMulE) +); + +/* Division unit */ +div_unit div_unit +( + .a(mux_ForwardDataAE), + .b(SrcBE), + .res(loDivE), + .rem(hiDivE) +); + +assign hiIn = + (MulDivRFE == 2'b00)? hiMulE : + (MulDivRFE == 2'b01)? hiDivE : + (MulDivRFE == 2'b10)? read_value1_out : 32'd0; + +assign loIn = + (MulDivRFE === 2'b00)? loMulE : + (MulDivRFE === 2'b01)? loDivE : + (MulDivRFE === 2'b10)? read_value1_out : 32'd0; + +/* ALU */ +alu alu +( + .a(mux_ForwardDataAE), + .b(SrcBE), + .f(ALUControlE), + .y(ALUoutE), .zero(zeroE), + .sign(SignE) +); + +/* Sign flag */ +assign SignE = ALUoutE[N-1]; + +/* Shifter */ +/* Choose Shift amount from instruction encoding or register */ +mux2 #(5) +shamt_reg_or_inst +( + .in1(SignImm_out[10:6]), + .in2(read_value1_out[4:0]), + .s(ShiftAmtVarE), + .out(ShiftAmtE) +); + +shift_unit shift_unit +( + .in(mux_ForwardDataBE), + .shamt(ShiftAmtE), + .shift_type(Shift_typeE), + .out(Shift_ResultE) +); + +mux2 aluout_or_shifterout +( + .in1(ALUoutEE), + .in2(Shift_ResultE), + .s(Shifter_or_ALUE), + .out(EX_Result) +); + +/* mux to choose between ALU output or its one's complement */ +mux2 aluout_or_comp +( + .in1(ALUoutE), + .in2(~ALUoutE), + .s(ALUCompE), + .out(ALUoutCompE) +); + +/* Normal or lui operation */ +mux2 normal_or_lui +( + .in1(ALUoutCompE), + .in2({ALUoutE[15:0],16'h0000}), + .s(UpperImmE), + .out(ALUoutEE) +); + +/* Calculate BTA */ +shift_left2 sl2 +( + .a(SignImm_out), + .out(shifted_imm_2) +); + +adder pcbranch_value +( + .in1(shifted_imm_2), + .in2(PCplus4E), + .cin(1'b0), + .out(PCBranchE) +); + +/* Calculate JTA */ +assign JTA_E = {PCplus4E[31:28], IR_E[25:0], 2'b00}; + +/****************************** EX/MEM Register ******************************** +* +* +*******************************************************************************/ +ex_mem_pipereg EX_MEM_REG +( + .clk(clk), + .reset(EX_MEM_RESET), + .en(EX_MEM_EN), + .opcode_in(opcodeE), + .zero_in(zeroE), + .sign_in(SignE), + .ALUout_in(EX_Result), + .WriteData_in(read_value2_out), + .PCBranch_in(PCBranchE), + .PCJump_in(JTA_E), + .WriteReg_in(WriteRegE), + + .RegWrite_in(RegWriteE), + .WBResultSelect_in(WBResultSelectE), + .MemWrite_in(MemWriteE), + .Branch_in(BranchE), + .Jump_in(JumpE), + .JumpR_in(JumpRE), + .BHW_in(bhwE), + .lo_in(loIn), + .hi_in(hiIn), + .loEN(loENE), + .hiEN(hiENE), + .link_in(linkE), + .pcplus4_in(PCplus4E), + .undefinedEx_in(undefinedExE), + .breakEx_in(breakExE), + .divbyZero_in(divbyZeroExE), + .syscallEx_in(syscallExE), + .CP0_wa_in(CP0_waE), + .CP0_ra_in(CP0_raE), + .CP0_Inst_in(CP0_InstE), + .CP0_dout_in(CP0_doutE), + .CP0_din_in(CP0_dinE), + .MemRefSize_in(MemRefSizeE), + + .zero_out(zeroM), + .sign_out(SignM), + .ALUout_out(ALUoutM), + .WriteData_out(WriteData_toDMemory), + .PCBranch_out(PCBranchM), + .WriteReg_out(WriteRegM), + + .RegWrite_out(RegWriteM), + .WBResultSelect_out(WBResultSelectM), + .MemWrite_out(MemWriteM), + .Branch_out(BranchM), + .Jump_out(JumpM), + .JumpR_out(JumpRM), + .BHW_out(bhwM), + .lo_out(loM), + .hi_out(hiM), + .opcode_out(opcodeM), + .PCJump_out(JTA_M), + .link_out(linkM), + .pcplus4_out(PCplus4M), + .undefinedEx_out(undefinedExM), + .breakEx_out(breakExM), + .divbyZero_out(divbyZeroExM), + .syscallEx_out(syscallExM), + .CP0_wa_out(CP0_waM), + .CP0_ra_out(CP0_raM), + .CP0_Inst_out(CP0_InstM), + .CP0_dout_out(CP0_doutM), + .CP0_din_out(CP0_dinM), + .MemRefSize_out(MemRefSizeM) +); + +/* output address to data memory in case of loads and stores and data to be +written into memory (stores) */ +assign Address_toDMemory = ALUoutM; + +/* output MemWrite Signal to data memory */ +assign MemWrite_toDMemory = MemWriteM; + +/* Get data from data memory */ +assign ReadDataM = RD_fromDMemory; + +/****************************** MEM/WB Register ******************************** +* +* +*******************************************************************************/ +mem_wb_pipereg MEM_WB_REG +( + .clk(clk), + .reset(reset), + .en(MEM_WB_EN), + + .ReadData_in(ReadDataM), + .ALUout_in(ALUoutM), + .WriteReg_in(WriteRegM), + .RegWrite_in(RegWriteM), + .WBResultSelect_in(WBResultSelectM), + .BHW_in(bhwM), + .lo_in(loM), + .hi_in(hiM), + .link_in(linkM), + .pcplus4_in(PCplus4M), + .undefinedEx_in(undefinedExM), + .breakEx_in(breakExM), + .divbyZero_in(divbyZeroExM), + .syscallEx_in(syscallExM), + .CP0_wa_in(CP0_waM), + .CP0_ra_in(CP0_raM), + .CP0_Inst_in(CP0_InstM), + .CP0_dout_in(CP0_doutM), + .CP0_din_in(CP0_dinM), + + .ReadData_out(ReadDataW), + .ALUout_out(ALUoutW), + .WriteReg_out(WriteRegW), + .RegWrite_out(RegWriteW), + .WBResultSelect_out(WBResultSelectW), + .BHW_out(bhwW), + .lo_out(loW), + .hi_out(hiW), + .link_out(linkW), + .pcplus4_out(PCplus4W), + .undefinedEx_out(undefinedExW), + .breakEx_out(breakExW), + .divbyZero_out(divbyZeroExW), + .syscallEx_out(syscallExW), + .CP0_wa_out(CP0_waW), + .CP0_ra_out(CP0_raW), + .CP0_Inst_out(CP0_InstW), + .CP0_dout_out(CP0_doutW) +); + + /* WBResult mux to choose between, ALUout, DataMemory, lo, hi */ +assign ResultW = + (WBResultSelectW === 2'b00) ? ALUoutW : + (WBResultSelectW === 2'b01) ? ReadDataW : + (WBResultSelectW === 2'b10) ? loW : hiW; + +endmodule
edge/trunk/HW/Verilog/edge_core.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/shift_unit.v =================================================================== --- edge/trunk/HW/Verilog/shift_unit.v (nonexistent) +++ edge/trunk/HW/Verilog/shift_unit.v (revision 2) @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////// +// // +// Shift unit for Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Shift unit handling different types of shifts : right, left,// +// arithmetic and logical. // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +`define SLL 2'b00 +`define SRL 2'b01 +`define SRA 2'b10 + +module shift_unit +#(parameter N=32) +( + input[N-1:0] in, + input[4:0] shamt, + input[1:0] shift_type, + + output reg[N-1:0] out +); + +wire[N-1:0] sl_result, srl_result, sra_result; + +shifter_left sl +( + .in(in), + .shamt(shamt), + .out(sl_result) +); + +shifter_right_logical +srl +( + .in(in), + .shamt(shamt), + .out(srl_result) +); + +shifter_right_arithmetic sra +( + .in(in), + .shamt(shamt), + .out(sra_result) +); + +always @(*) + case (shift_type) + `SLL: out <= sl_result; + `SRL: out <= srl_result; + `SRA: out <= sra_result; + default: out <= in; + endcase + +endmodule Index: edge/trunk/HW/Verilog/regfile.v =================================================================== --- edge/trunk/HW/Verilog/regfile.v (nonexistent) +++ edge/trunk/HW/Verilog/regfile.v (revision 2) @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////// +// // +// Register file for Edge core. // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// General purpose 32 x 32 bit register file // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module regfile +( + clk, + reset, + ra1, + ra2, + wa3, + we3, + wd3, + rd1, + rd2 +); +/* Bus size in bits for data */ +parameter N = 32; +/* Bus size in bits for Addresses, the register file size should be 2**addr_size */ +parameter addr_size = 5; + +/* Specify IO sizes */ +input wire clk; +input wire reset; +input wire[addr_size-1:0] ra1; +input wire[addr_size-1:0]ra2; +input wire[addr_size-1:0]wa3; +input wire we3; +input wire[N-1:0] wd3; +output reg[N-1:0] rd1; +output reg[N-1:0] rd2; +integer i; + +/* Define register file*/ +reg[N-1:0] rf [(2**addr_size)-1:0]; + +initial +begin + for(i=0; i<32; i=i+1) + rf[i] = 0; +end + +always @(posedge clk) + if (we3) + rf[wa3] = wd3; + +always @(negedge clk) +begin + rd1 = (ra1 != 0)? rf[ra1]:0; + rd2 = (ra2 != 0)? rf[ra2]:0; +end + +endmodule +
edge/trunk/HW/Verilog/regfile.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/shifter_left.v =================================================================== --- edge/trunk/HW/Verilog/shifter_left.v (nonexistent) +++ edge/trunk/HW/Verilog/shifter_left.v (revision 2) @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////// +// // +// Shift left unit for Edge Core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Shift left unit for Edge Core // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module shifter_left +# +( + parameter N=32, SA=5 +) +( + input[N-1:0] in, + input[4:0] shamt, + output[N-1:0] out +); + +assign out = in << shamt; + +endmodule Index: edge/trunk/HW/Verilog/adder.v =================================================================== --- edge/trunk/HW/Verilog/adder.v (nonexistent) +++ edge/trunk/HW/Verilog/adder.v (revision 2) @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////// +// // +// N bit Adder for Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// N bit adder with carry in and carry out // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module adder +# +( + parameter N = 32 +) +( + input [N-1:0]in1, + input [N-1:0]in2, + input cin, + output cout, + output [N-1:0]out +); + +assign {cout,out} = in1 + in2 + cin; + +endmodule
edge/trunk/HW/Verilog/adder.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/mult_unit.v =================================================================== --- edge/trunk/HW/Verilog/mult_unit.v (nonexistent) +++ edge/trunk/HW/Verilog/mult_unit.v (revision 2) @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////// +// // +// Multiplication unit for Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Multiplication unit for Edge core // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module mult_unit +# +( + parameter N=32 +) +( + input[N-1:0] a, + input[N-1:0] b, + output[N-1:0] hi, + output[N-1:0] lo +); + +assign {hi,lo} = a * b; + +endmodule Index: edge/trunk/HW/Verilog/alu.v =================================================================== --- edge/trunk/HW/Verilog/alu.v (nonexistent) +++ edge/trunk/HW/Verilog/alu.v (revision 2) @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////// +// // +// Arithmetic and logic unit (ALU) for Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// ALU supports add, sub, and, or and mul functions. // +// Also it outputs zero and sign flags. // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module alu +# +( + parameter N=32 +) +( + input [N-1:0] a, b, + input [3:0] f, + output reg[N-1:0] y, + output zero, + output sign +); + +wire [N-1:0] b_mux2_out; +wire [N-1:0] adder_out, tmp; +wire cout; + +// first level mux +mux2 mux2_out(b, ~b, f[2], b_mux2_out); + +// Adder output +adder adder(a, b_mux2_out, f[2], cout, adder_out); + +always @* +begin + if(f[3] == 0) + begin + case(f[1:0]) + 0: y = a & b_mux2_out; + 1: y = a | b_mux2_out; + 2: y = adder_out; + 3: y = f[2] ? ((adder_out[N-1] == 1'b1) ? 1 : 0) : + (a ^ b_mux2_out); + default : y = 0; + endcase + end + else // f[3] == 1 + begin + case(f[2:0]) + 3'b000: y = a * b; + default : y = 0; + endcase + end +end + +assign zero = (y == 0) ? 1'b1:1'b0; +assign sign = y[N-1]; + +endmodule +
edge/trunk/HW/Verilog/alu.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/mem_wb_pipereg.v =================================================================== --- edge/trunk/HW/Verilog/mem_wb_pipereg.v (nonexistent) +++ edge/trunk/HW/Verilog/mem_wb_pipereg.v (revision 2) @@ -0,0 +1,253 @@ +////////////////////////////////////////////////////////////////// +// // +// MEM/WB pipeline register // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Pipeline register lies between memory and write back stages // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module mem_wb_pipereg +# +( + parameter N=32, /* most registers sizes */ + parameter M=5 +) /* regfile address */ +( + input clk, + input reset, + input en, + + input[N-1:0] ReadData_in, + input[N-1:0] ALUout_in, + input[M-1:0] WriteReg_in, + input RegWrite_in, + input[1:0] WBResultSelect_in, + input[2:0] BHW_in, /* byte or halfword or word ? */ + input[N-1:0] lo_in, + input[N-1:0] hi_in, + input[N-1:0] pcplus4_in, + input link_in, + + /* Coprocessor0 and exceptions signals */ + input undefinedEx_in, + input breakEx_in, + input divbyZero_in, + input syscallEx_in, + + input[M-1:0] CP0_wa_in, + input[M-1:0] CP0_ra_in, + input[1:0] CP0_Inst_in, + input[N-1:0] CP0_dout_in, + input[N-1:0] CP0_din_in, + + input[1:0] MemRefSize_in, + + output[N-1:0] ReadData_out, + output[N-1:0] ALUout_out, + output[M-1:0] WriteReg_out, + output RegWrite_out, + output[1:0] WBResultSelect_out, + output[2:0] BHW_out, /* byte or halfword or word ? */ + output[N-1:0] lo_out, + output[N-1:0] hi_out, + output[N-1:0] pcplus4_out, + output link_out, + + /* Coprocessor0 and exceptions signals */ + output undefinedEx_out, + output breakEx_out, + output divbyZero_out, + output syscallEx_out, + + output[M-1:0] CP0_wa_out, + output[M-1:0] CP0_ra_out, + output[1:0] CP0_Inst_out, + output[N-1:0] CP0_dout_out, + output[N-1:0] CP0_din_out, + + output[1:0] MemRefSize_out +); + +/* Read data from memory in case of load instruction */ +register ReadData +( + .clk(clk), .reset(reset), .en(en), + .d(ReadData_in), + .q(ReadData_out) +); + +/* ALU output R-type */ +register ALUout +( + .clk(clk), .reset(reset), .en(en), + .d(ALUout_in), + .q(ALUout_out) +); + +/* PC plus 4 */ +register pcplus4 +( + .clk(clk), .reset(reset), .en(en), + .d(pcplus4_in), + .q(pcplus4_out) +); + +/* hi, lo special purpose registers */ +register lo(.clk(clk), .reset(reset), .en(en), .d(lo_in), .q(lo_out)); +register hi(.clk(clk), .reset(reset), .en(en), .d(hi_in), .q(hi_out)); + +/* Write Register Address */ +register #(5) +WriteReg +( + .clk(clk), .reset(reset), .en(en), + .d(WriteReg_in), + .q(WriteReg_out) +); + +/* Control Signal */ +register #(1) +link +( + .clk(clk), .reset(reset), .en(en), + .d(link_in), + .q(link_out) +); + +register #(1) +RegWrite +( + .clk(clk), .reset(reset), .en(en), + .d(RegWrite_in), + .q(RegWrite_out) +); + +register #(2) +WBResultSelect +( + .clk(clk), .reset(reset), .en(en), + .d(WBResultSelect_in), + .q(WBResultSelect_out) +); + +register #(3) +BHW +( + .clk(clk), .reset(reset), .en(en), + .d(BHW_in), + .q(BHW_out) +); + +/* Coprocessor zero related */ +register #(1) +undefinedEx +( + .clk(clk), .reset(reset), .en(en), + .d(undefinedEx_in), + .q(undefinedEx_out) +); + +register #(1) +breakEx +( + .clk(clk), .reset(reset), .en(en), + .d(breakEx_in), + .q(breakEx_out) +); + +register #(1) +divbyZero +( + .clk(clk), .reset(reset), .en(en), + .d(divbyZero_in), + .q(divbyZero_out) +); + +register #(1) +syscallEx +( + .clk(clk), .reset(reset), .en(en), + .d(syscallEx_in), + .q(syscallEx_out) +); + +register #(5) +CP0_wa +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_wa_in), + .q(CP0_wa_out) +); + +register #(5) +CP0_ra +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_ra_in), + .q(CP0_ra_out) +); + +register #(2) +CP0_Inst +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_Inst_in), + .q(CP0_Inst_out) +); + +register CP0_dout +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_dout_in), + .q(CP0_dout_out) +); + +register CP0_din +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_din_in), + .q(CP0_din_out) +); + +/* Memory referece sizes */ +register #(2) +MemRefSize +( + .clk(clk), .reset(reset), .en(en), + .d(MemRefSize_in), + .q(MemRefSize_out) +); + +endmodule
edge/trunk/HW/Verilog/mem_wb_pipereg.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/div_unit.v =================================================================== --- edge/trunk/HW/Verilog/div_unit.v (nonexistent) +++ edge/trunk/HW/Verilog/div_unit.v (revision 2) @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////// +// // +// Division unit for Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Divison unit functions : divide and mod // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module div_unit +# +( + parameter N = 32 +) +( + input[N-1:0] a, + input[N-1:0] b, + output[N-1:0] res, /* result */ + output[N-1:0] rem /* remainder */ +); + +assign res = a / b; +assign rem = a % b; + +endmodule Index: edge/trunk/HW/Verilog/Coprocessor0.v =================================================================== --- edge/trunk/HW/Verilog/Coprocessor0.v (nonexistent) +++ edge/trunk/HW/Verilog/Coprocessor0.v (revision 2) @@ -0,0 +1,150 @@ +////////////////////////////////////////////////////////////////// +// // +// Coprocessor0 for Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Coprocessor0 in MIPS is the control unit mainly respobsible // +// for handling interrupts. // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +/* Coprocessor 0 instructions definitions */ +`define EXCEPTION 1 /* Take exception, save EPC and Cause */ +`define READ_REG 2 /* Read one of Coprocessor0 registers mfc0, lwc0 */ +`define WRITE_REG 3 /* Write to Coprocessor0 Registers */ + +/* Clock definitions */ +`define SYSCLK 50000000 //25MHz +`define MS_LIMIT `SYSCLK / 1000 // 1MS counter limit + +module Coprocessor0 +# +( + parameter N=32, + parameter M=5 +) +( + input clk, + input [N-1:0] EPC, + input [N-1:0] Cause, + input [1:0] instruction, + input [M-1:0] ra, /* Read address */ + input [M-1:0] wa, /* Write address */ + input [N-1:0] WriteData, + input IO_TimerIntReset, /* reset timer from software */ + + output[N-1:0] ReadData, + output TimerIntMatch +); + +/********* Coprocessor0 currently supported registers ******* +* 0 +* 1 +* 2 +* 3 +* 4 +* 5 +* 6 +* 7 +* 8 +* 9 Counter +* 10 +* 11 Compare +* 12 Status +* 13 Cause +* 14 EPC +* 15 +* 16 +* 17 +* 18 +* 19 +* 20 +* 21 +* 22 +*************************************************************/ +reg[N-1:0] rf [(2**M)-1:0]; + +reg TimerMatch = 0; /* Count = Compare */ + +assign TimerIntMatch = TimerMatch; + +reg[31:0] ClockCycleCount = 0; +reg[63:0] Counter = 0; +integer i = 0; + +initial +begin + for(i=0; i<32; i=i+1) + rf[i] = 0; +end + +always @(posedge clk) +begin + + + case (instruction) + `EXCEPTION: + begin + rf[13] = Cause; + rf[14] = EPC; + end + `WRITE_REG: + rf[wa] = WriteData; + endcase + + /* Timer operations */ + Counter = Counter + 1; + + if(Counter == `MS_LIMIT) // 1MS passed + begin + rf[9] = rf[9] + 1; + Counter = 0; + end + + if(rf[9] == rf[11]) + TimerMatch = 1; + + if(IO_TimerIntReset) + begin + rf[9] = 0; + TimerMatch = 0; + Counter = 0; + end + /* Timer operation */ + +end + +assign ReadData = rf[ra]; + +endmodule Index: edge/trunk/HW/Verilog/controller.v =================================================================== --- edge/trunk/HW/Verilog/controller.v (nonexistent) +++ edge/trunk/HW/Verilog/controller.v (revision 2) @@ -0,0 +1,420 @@ +////////////////////////////////////////////////////////////////// +// // +// Instruction decoder at decode stage for Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Instruction decoder receives MIPS instruction and emits the // +// appropriate control signal for each unit in the pipeline. // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +/* OPCODE defines INST[31:26] */ +`define RTYPE_OPCODE 6'b000000 // 0 + +/* Immediates */ +`define ADDI_OPCODE 6'b001000 // 8 +`define ADDIU_OPCODE 6'b001001 // 9 +`define SLTI_OPCODE 6'b001010 // 10 +`define SLTIU_OPCODE 6'b001011 // 11 +`define ANDI_OPCODE 6'b001100 // 12 +`define ORI_OPCODE 6'b001101 // 13 +`define XORI_OPCODE 6'b001110 // 14 + +/* loads */ +`define LUI_OPCODE 6'b001111 // 15 +`define CP0_OPCODE 6'b010000 // 16 mfc0, mtc0 +`define MUL_OPCODE 6'b011100 // 28 +`define LB_OPCODE 6'b100000 // 32 +`define LH_OPCODE 6'b100001 // 33 +`define LW_OPCODE 6'b100011 // 35 +`define LBU_OPCODE 6'b100100 // 36 +`define LHU_OPCODE 6'b100101 // 37 + +`define SB_OPCODE 6'b101000 // 40 +`define SH_OPCODE 6'b101001 // 41 +`define SW_OPCODE 6'b101011 // 43 + +`define BLTZ_OPCODE 6'b000001 // 1 +`define BGEZ_OPCODE 6'b000001 // 1 +`define JMP_OPCODE 6'b000010 // 2 +`define JAL_OPCODE 6'b000011 // 3 +`define BEQ_OPCODE 6'b000100 // 4 +`define BNE_OPCODE 6'b000101 // 5 +`define BLEZ_OPCODE 6'b000110 // 6 +`define BGTZ_OPCODE 6'b000111 // 7 + +/* FUNCT defines INST[5:0] */ +`define SLL_FUNCT 6'b000000 // 0 +`define SRL_FUNCT 6'b000010 // 2 +`define SRA_FUNCT 6'b000011 // 3 +`define SLLV_FUNCT 6'b000100 // 4 +`define SRLV_FUNCT 6'b000110 // 6 +`define SRAV_FUNCT 6'b000111 // 7 +`define JR_FUNCT 6'b001000 // 8 +`define JALR_FUNCT 6'b001001 // 9 +`define SYSCALL_FUNCT 6'b001100 // 12 +`define BREAK_FUNCT 6'b001101 // 13 +`define MFHI_FUNCT 6'b010000 // 16 +`define MTHI_FUNCT 6'b010001 // 17 +`define MFLO_FUNCT 6'b010010 // 18 +`define MTLO_FUNCT 6'b010011 // 19 +`define MULT_FUNCT 6'b011000 // 24 +`define MULTU_FUNCT 6'b011001 // 25 +`define DIV_FUNCT 6'b011010 // 26 +`define DIVU_FUNCT 6'b011011 // 27 +`define ADD_FUNCT 6'b100000 // 32 +`define ADDU_FUNCT 6'b100001 // 33 +`define SUB_FUNCT 6'b100010 // 34 +`define SUBU_FUNCT 6'b100011 // 35 +`define AND_FUNCT 6'b100100 // 36 +`define OR_FUNCT 6'b100101 // 37 +`define XOR_FUNCT 6'b100110 // 38 +`define SLT_FUNCT 6'b101010 // 42 +`define SLTU_FUNCT 6'b101011 // 43 + +/* Memory Reference sizes */ +`define BYTE_REF 2'b01 +`define HW_REF 2'b10 +`define W_REF 2'b11 + +module controller +( + input[5:0] opcode, + input[5:0] func, + input[31:0] Instruction, + + output reg RegWrite, + output reg[1:0] WBResultSelect, + output reg MemWrite, + output reg Branch, + output reg Jump, + output reg JumpR, /* Jump to address in Register */ + output [3:0] ALUControl, + output reg ALUSrcB, + output reg RegDst, + output reg UpperImm_out, + output reg [2:0] BHW, /* byte or halfword or word ? */ + output reg ImmSorU_out, /* Signed or Unsgined Immediate ? */ + output reg ALUComp_out, /* One complement of ALU output (useful for inst +like nor */ + output ShiftAmtVar_out, /* Whether shift amount comes from instruction +or register */ + output [1:0] Shift_type_out, /* Choose shifter type from [Right | LEFT] +[Logical | Arithmetic] */ + output reg Shifter_or_ALU_out, /* Choose Result between ALUoutput and +Shifter output */ + output reg[1:0] MulDivRF, /* Choose input to hi/lo registers from Mul, Div, +or RF */ + output reg hiEN, /* Enable(load) hi register */ + output reg loEN, /* Enable(load) lo register */ + output reg link, /* if link == 1 > Put pc+4 into ra */ + output reg undefinedEx, /* Undefined instruction Excption */ + output reg syscallEx, /* System call excpetion */ + output reg breakEx, /* Break expetion */ + output reg mfc0, /* get value from coprocessor 0 */ + output reg mtc0, /* Write enable Co-processor 0 registers */ + output reg[1:0] MemRefSize /* Zero of no mem ref, 1 for byte, 2 for hw, 3 +for w)*/ +); + +reg[3:0] ALUop; + +always @* +begin + RegWrite = 1'b0; + WBResultSelect <= 2'b00; + MemWrite <= 1'b0; + Branch <= 1'b0; + Jump <= 1'b0; + JumpR <= 1'b0; + ALUSrcB <= 1'b0; + RegDst <= 1'b0; + ALUop <= 4'b0000; + UpperImm_out <= 1'b0; + BHW <= 3'b000; + ImmSorU_out <= 0; + ALUComp_out <= 0; + Shifter_or_ALU_out <= 0; + MulDivRF <= 2'b11; /* Zero hi, lo registers */ + hiEN <= 1'b0; + loEN <= 1'b0; + link <= 1'b0; + undefinedEx <= 1'b0; + syscallEx <= 1'b0; + breakEx <= 1'b0; + mfc0 <= 1'b0; + mtc0 <= 1'b0; + MemRefSize = 2'b00; /* No memory reference */ + + /* Every new instruction opcode should be added here */ + + case (opcode) + `RTYPE_OPCODE: /* R-Type */ + begin + RegWrite = 1'b1; + ALUop <= 4'b0010; + RegDst <= 1'b1; + + if (func == `SLL_FUNCT || func == `SRL_FUNCT || + func == `SRA_FUNCT || func == `SLLV_FUNCT|| + func == `SRLV_FUNCT|| func == `SRAV_FUNCT) /* Shift Operation */ + Shifter_or_ALU_out <= 1; + if (func == `JR_FUNCT) + begin + JumpR <= 1'b1; + RegWrite = 1'b0; + ALUop <= 4'b0000; + end + if (func == `JALR_FUNCT) + begin + JumpR <= 1'b1; + RegWrite = 1'b1; + ALUop <= 4'b0000; + link <= 1'b1; + end + case(func) + `MTHI_FUNCT : + begin + RegWrite = 1'b0; + hiEN <= 1'b1; + MulDivRF <= 2'b10; + end + `MTLO_FUNCT : + begin + RegWrite = 1'b0; + loEN <= 1'b1; + MulDivRF <= 2'b10; + end + `MULT_FUNCT : + begin + RegWrite = 1'b0; + hiEN <= 1'b1; + loEN <= 1'b1; + MulDivRF <= 2'b00; + end + `MULTU_FUNCT : + begin + RegWrite = 1'b0; + hiEN <= 1'b1; + loEN <= 1'b1; + MulDivRF <= 2'b00; + end + `DIV_FUNCT : + begin + RegWrite = 1'b0; + hiEN <= 1'b1; + loEN <= 1'b1; + MulDivRF <= 2'b01; + end + `DIVU_FUNCT : + begin + RegWrite = 1'b0; + hiEN <= 1'b1; + loEN <= 1'b1; + MulDivRF <= 2'b01; + end + `MFLO_FUNCT: + WBResultSelect <= 2'b10; + `MFHI_FUNCT: + WBResultSelect <= 2'b11; + `SYSCALL_FUNCT: + syscallEx <= 1'b1; + `BREAK_FUNCT: + breakEx <= 1'b1; + endcase + + end + `ADDI_OPCODE: + begin + RegWrite = 1'b1; + ALUSrcB <= 1'b1; + end + `ADDIU_OPCODE: + begin + RegWrite = 1'b1; + ALUSrcB <= 1'b1; + end + `SLTI_OPCODE: + begin + RegWrite = 1'b1; + ALUop <= 4'b100; + ALUSrcB <= 1'b1; + end + `SLTIU_OPCODE: + begin + RegWrite = 1'b1; + ALUop <= 4'b0010; + ALUSrcB <= 1'b1; + ImmSorU_out <= 1'b1; + end + `ANDI_OPCODE: + begin + RegWrite = 1'b1; + ALUop <= 4'b0101; + ALUSrcB <= 1'b1; + end + `ORI_OPCODE: + begin + RegWrite = 1'b1; + ALUop <= 4'b0110; + ALUSrcB <= 1'b1; + end + `XORI_OPCODE: + begin + RegWrite = 1'b1; + ALUop <= 4'b0111; + ALUSrcB <= 1'b1; + end + `MUL_OPCODE: + begin + RegWrite = 1'b1; + ALUop <= 4'b1000; + RegDst <= 1'b1; + end + `LUI_OPCODE: /* Load upper immediate */ + begin + UpperImm_out <= 1'b1; + RegWrite = 1'b1; + ALUSrcB <= 1'b1; + end + `LB_OPCODE: /* load signed byte */ + begin + RegWrite = 1'b1; + WBResultSelect <= 2'b01; + ALUSrcB <= 1'b1; + BHW <= 3'b001; + MemRefSize = 2'b01; + end + `LH_OPCODE: /* load signed halfword */ + begin + RegWrite = 1'b1; + WBResultSelect <= 2'b01; + ALUSrcB <= 1'b1; + BHW <= 3'b010; + MemRefSize = 2'b10; + end + `LW_OPCODE: /* load word */ + begin + RegWrite = 1'b1; + WBResultSelect <= 2'b01; + ALUSrcB <= 1'b1; + MemRefSize = 2'b11; + end + `LBU_OPCODE: /* load unsigned byte */ + begin + RegWrite = 1'b1; + WBResultSelect <= 2'b01; + ALUSrcB <= 1'b1; + BHW <= 3'b011; + MemRefSize = 2'b01; + end + `LHU_OPCODE: /* load unsigned byte */ + begin + RegWrite = 1'b1; + WBResultSelect <= 2'b01; + ALUSrcB <= 1'b1; + BHW <= 3'b100; + MemRefSize = 2'b10; + end + `SB_OPCODE: + begin + MemWrite <= 1'b1; + ALUSrcB <= 1'b1; + MemRefSize = 2'b01; + end + `SH_OPCODE: + begin + MemWrite <= 1'b1; + ALUSrcB <= 1'b1; + MemRefSize = 2'b10; + end + `SW_OPCODE: /* store */ + begin + MemWrite <= 1'b1; + ALUSrcB <= 1'b1; + MemRefSize = 2'b11; + end + `BEQ_OPCODE, + `BNE_OPCODE: /* branch if equale */ + begin + Branch <= 1'b1; + ALUop <= 4'b0001; + end + `BLTZ_OPCODE, `BGEZ_OPCODE, `BLEZ_OPCODE, `BGTZ_OPCODE: + begin + Branch <= 1'b1; + end + `JMP_OPCODE: + Jump <= 1'b1; + `JAL_OPCODE: + begin + Jump <= 1'b1; + link <= 1'b1; + RegWrite = 1'b1; + end + `CP0_OPCODE: + begin + if(Instruction[25:21] == 5'd0) //mfc0 + begin + mfc0 <= 1'b1; + RegWrite = 1'b1; + RegDst <= 1'b0; + end + else if(Instruction[25:21] == 5'd4) //mtc0 + begin + mtc0 <= 1'b1; + end + end + default: /* Undefined instruction exception */ + begin + undefinedEx <= 1'b1; + end + endcase +end + +alu_decoder dec +( +.ALUop(ALUop), +.Funct(func), +.ALUControl(ALUControl) +); + +shifter_decoder shift_dec +( +.Funct(func), +.Shift_type(Shift_type_out), +.ShiftAmtVar_out(ShiftAmtVar_out) +); + +endmodule
edge/trunk/HW/Verilog/controller.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/register.v =================================================================== --- edge/trunk/HW/Verilog/register.v (nonexistent) +++ edge/trunk/HW/Verilog/register.v (revision 2) @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////// +// // +// Register module for Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// General purpose register module. // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module register +#( + parameter N=32 +) +( + input clk, + input reset, + input en, + input[N-1:0] d, + output reg[N-1:0] q +); + +always @(posedge clk) + if(reset) + q = 0; + else if (en) + q = d; + +endmodule
edge/trunk/HW/Verilog/register.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/if_id_pipereg.v =================================================================== --- edge/trunk/HW/Verilog/if_id_pipereg.v (nonexistent) +++ edge/trunk/HW/Verilog/if_id_pipereg.v (revision 2) @@ -0,0 +1,81 @@ +////////////////////////////////////////////////////////////////// +// // +// IF/ID pipeline register // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Pipeline register lies between fetch and decode stages // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module if_id_pipereg +# +( + parameter N=32, /* most registers sizes */ + parameter M=5 +) /* regfile address */ +( + input clk, + input reset, + input en, + input [N-1:0] IR_in, + input [N-1:0] PCplus4_in, + input [N-1:0] PC_in, + output [N-1:0] IR_out, + + output [N-1:0] PC_out, + output [N-1:0] PCplus4_out +); + +register IR +( + .clk(clk), .reset(reset), .en(en), + .d(IR_in), + .q(IR_out) +); + +register PC_4 +( + .clk(clk), .reset(reset), .en(en), + .d(PCplus4_in), + .q(PCplus4_out) +); + +register PC +( + .clk(clk), .reset(reset), .en(en), + .d(PC_in), + .q(PC_out) +); + +endmodule
edge/trunk/HW/Verilog/if_id_pipereg.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/ex_mem_pipereg.v =================================================================== --- edge/trunk/HW/Verilog/ex_mem_pipereg.v (nonexistent) +++ edge/trunk/HW/Verilog/ex_mem_pipereg.v (revision 2) @@ -0,0 +1,366 @@ +////////////////////////////////////////////////////////////////// +// // +// EX/MEM pipeline register // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Pipeline register lies between execute and memory stages // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module ex_mem_pipereg +# +( parameter N=32, + parameter M=5 +) +( + input clk, + input reset, + input en, + input zero_in, + input sign_in, + input[N-1:0] ALUout_in, + input[N-1:0] WriteData_in, + input[N-1:0] PCBranch_in, + input[N-1:0] PCJump_in, + input[M-1:0] WriteReg_in, + input RegWrite_in, + input[1:0] WBResultSelect_in, + + input[5:0] opcode_in, + input MemWrite_in, + input Branch_in, + input Jump_in, + input JumpR_in, + input[2:0] BHW_in, /* byte or halfword or word ? */ + input[N-1:0] lo_in, + input[N-1:0] hi_in, + input loEN, + input hiEN, + input[N-1:0] pcplus4_in, + input link_in, + + /* Coprocessor0 and exceptions signals */ + input undefinedEx_in, + input breakEx_in, + input divbyZero_in, + input syscallEx_in, + + input[M-1:0] CP0_wa_in, + input[M-1:0] CP0_ra_in, + input[1:0] CP0_Inst_in, + input[N-1:0] CP0_dout_in, + input[N-1:0] CP0_din_in, + + input[1:0] MemRefSize_in, + + output zero_out, + output sign_out, + output[N-1:0] ALUout_out, + output[N-1:0] WriteData_out, + output[N-1:0] PCBranch_out, + output[N-1:0] PCJump_out, + output[M-1:0] WriteReg_out, + output RegWrite_out, + output[1:0] WBResultSelect_out, + output MemWrite_out, + output Branch_out, + output Jump_out, + output JumpR_out, + output[2:0] BHW_out, /* byte or halfword or word ? */ + output[N-1:0] lo_out, + output[N-1:0] hi_out, + output[5:0] opcode_out, + output[N-1:0] pcplus4_out, + output link_out, + + /* Coprocessor0 and exceptions signals */ + output undefinedEx_out, + output breakEx_out, + output divbyZero_out, + output syscallEx_out, + + output[M-1:0] CP0_wa_out, + output[M-1:0] CP0_ra_out, + output[1:0] CP0_Inst_out, + output[N-1:0] CP0_dout_out, + output[N-1:0] CP0_din_out, + + output[1:0] MemRefSize_out +); + +/* Opcode */ +register #(6) +opcode +( + .clk(clk), .reset(reset), .en(en), + .d(opcode_in), + .q(opcode_out) +); + +/* Zero flag */ +register #(1) +zero +( + .clk(clk), .reset(reset), .en(en), + .d(zero_in), + .q(zero_out) +); + +/* Sign Flag */ +register #(1) +sign +( + .clk(clk), .reset(reset), .en(en), + .d(sign_in), + .q(sign_out) +); + +/* ALU output */ +register ALUout +( + .clk(clk), .reset(reset), .en(en), + .d(ALUout_in), + .q(ALUout_out) +); + +/* PC plus 4 */ +register pcplus4 +( + .clk(clk), .reset(reset), .en(en), + .d(pcplus4_in), + .q(pcplus4_out) +); + +/* hi, lo special purpose registers */ +register lo +( + .clk(clk), .reset(0), .en(loEN), + .d(lo_in), + .q(lo_out) +); + +register hi +( + .clk(clk), .reset(0), .en(hiEN), + .d(hi_in), + .q(hi_out) +); + +/* Write data in case of store instruction */ +register WriteData +( + .clk(clk), .reset(reset), .en(en), + .d(WriteData_in), + .q(WriteData_out) +); + +/* Calcualted branch address */ +register PCBranch +( + .clk(clk), .reset(reset), .en(en), + .d(PCBranch_in), + .q(PCBranch_out) +); + +/* Caluculated jump address */ +register PCJump +( + .clk(clk), .reset(reset), .en(en), + .d(PCJump_in), + .q(PCJump_out) +); + +/* Write Register address */ +register #(5) +WriteReg +( + .clk(clk), .reset(reset), .en(en), + .d(WriteReg_in), + .q(WriteReg_out) +); + +/* Control Signal */ +register #(1) +RegWrite +( + .clk(clk), .reset(reset), .en(en), + .d(RegWrite_in), + .q(RegWrite_out) +); + +register #(1) +link +( + .clk(clk), .reset(reset), .en(en), + .d(link_in), + .q(link_out) +); + +register #(2) +WBResultSelect +( + .clk(clk), .reset(reset), .en(en), + .d(WBResultSelect_in), + .q(WBResultSelect_out) +); + +register #(1) +MemWrite +( + .clk(clk), .reset(reset), .en(en), + .d(MemWrite_in), + .q(MemWrite_out) +); + +register #(1) +Branch +( + .clk(clk), .reset(reset), .en(en), + .d(Branch_in), + .q(Branch_out) +); + +register #(1) +Jump +( + .clk(clk), + .reset(reset), + .en(en), + .d(Jump_in), + .q(Jump_out) +); + +register #(1) +JumpR +( + .clk(clk), .reset(reset), .en(en), + .d(JumpR_in), + .q(JumpR_out) +); + +register #(3) +BHW +( + .clk(clk), .reset(reset), .en(en), + .d(BHW_in), + .q(BHW_out) +); + +/* Coprocessor zero related */ +register #(1) +undefinedEx +( + .clk(clk), .reset(reset), .en(en), + .d(undefinedEx_in), + .q(undefinedEx_out) +); + +register #(1) +breakEx +( + .clk(clk), + .reset(reset), + .en(en), + .d(breakEx_in), + .q(breakEx_out) +); + +register #(1) +divbyZero +( + .clk(clk), + .reset(reset), + .en(en), + .d(divbyZero_in), + .q(divbyZero_out) +); + +register #(1) +syscallEx +( + .clk(clk), .reset(reset), .en(en), + .d(syscallEx_in), + .q(syscallEx_out) +); + +register #(5) +CP0_wa +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_wa_in), + .q(CP0_wa_out) +); + +register #(5) +CP0_ra +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_ra_in), + .q(CP0_ra_out) +); + +register #(2) +CP0_Inst +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_Inst_in), + .q(CP0_Inst_out) +); + +register CP0_dout +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_dout_in), + .q(CP0_dout_out) +); + +register CP0_din +( + .clk(clk), + .reset(reset), + .en(en), + .d(CP0_din_in), + .q(CP0_din_out) +); + +/* Memory referece sizes */ +register #(2) +MemRefSize +( + .clk(clk), .reset(reset), .en(en), + .d(MemRefSize_in), + .q(MemRefSize_out) +); + +endmodule
edge/trunk/HW/Verilog/ex_mem_pipereg.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/clock_manager.v =================================================================== --- edge/trunk/HW/Verilog/clock_manager.v (nonexistent) +++ edge/trunk/HW/Verilog/clock_manager.v (revision 2) @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////// +// // +// Clock manager for Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// The clock manager depends on counter concept to output the // +// desired clock frequency. // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module clock_manager +# +( + parameter SYSCLK = 100000000, // 100 MHz for atlys board + parameter CLK_OUT = 100000000, // desizred clock output + parameter DIV=1, + parameter MUL=1 +) +( + input clk_in, + output clk_out +); + +reg[31:0] counter = 0; +reg clk_buffer = 0; + +always @(posedge clk_in) +begin + if(counter == 32'd0) + clk_buffer = ~clk_buffer; + + counter = counter + 1; + + if (counter == (SYSCLK/CLK_OUT)/2) + counter = 31'd0; +end + +assign clk_out = clk_buffer; + +endmodule Index: edge/trunk/HW/Verilog/zero_extend.v =================================================================== --- edge/trunk/HW/Verilog/zero_extend.v (nonexistent) +++ edge/trunk/HW/Verilog/zero_extend.v (revision 2) @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////// +// // +// Zero extend unit for Edge Core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Zero extend unit for Edge Core // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module zero_extend +# +( + parameter N = 32, + parameter INSize = 16 +) +( + input[INSize-1:0] in, + output[N-1:0] out +); + +assign out = {{(N-INSize){1'b0}},in}; + +endmodule Index: edge/trunk/HW/Verilog/shift_left.v =================================================================== --- edge/trunk/HW/Verilog/shift_left.v (nonexistent) +++ edge/trunk/HW/Verilog/shift_left.v (revision 2) @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////// +// // +// Shift by 2 bits // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Shifting input by 2 bits (Should be supressed in future) // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module shift_left2 +# +( + parameter N = 32 +) +( + input[N-1:0] a, + output[N-1:0] out +); + +assign out = {a[29:0],2'b00}; + +endmodule
edge/trunk/HW/Verilog/shift_left.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/shifter_decoder.v =================================================================== --- edge/trunk/HW/Verilog/shifter_decoder.v (nonexistent) +++ edge/trunk/HW/Verilog/shifter_decoder.v (revision 2) @@ -0,0 +1,92 @@ +////////////////////////////////////////////////////////////////// +// // +// Shift decoder for Edge Core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Shift decoder is part of the main controller/decoder at // +// decode stage. It decodes MIPS instruction and produces // +// control signals for the shift unit. +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +/* Shift unit control */ +`define SLL_CTRL 2'b00 +`define SRL_CTRL 2'b01 +`define SRA_CTRL 2'b10 + +/* Shift Encoding */ +`define SLL_FUNCT 6'b000000 // 0 +`define SRL_FUNCT 6'b000010 // 2 +`define SRA_FUNCT 6'b000011 // 3 +`define SLLV_FUNCT 6'b000100 // 4 +`define SRLV_FUNCT 6'b000110 // 6 +`define SRAV_FUNCT 6'b000111 // 7 + +module shifter_decoder +( + input[5:0] Funct, + + output reg ShiftAmtVar_out, + output reg[1:0] Shift_type +); + +always @* +begin + ShiftAmtVar_out = 1'b0; + Shift_type <= 2'b00; + + case (Funct) + `SLL_FUNCT : Shift_type <= `SLL_CTRL; + `SLLV_FUNCT : + begin + Shift_type <= `SLL_CTRL; + ShiftAmtVar_out = 1'b1; + end + `SRL_FUNCT : Shift_type <= `SRL_CTRL; + `SRLV_FUNCT : + begin + Shift_type <= `SRL_CTRL; + ShiftAmtVar_out = 1'b1; + end + `SRA_FUNCT : Shift_type <= `SRA_CTRL; + `SRAV_FUNCT : + begin + Shift_type <= `SRA_CTRL; + ShiftAmtVar_out = 1'b1; + end + + endcase +end + +endmodule Index: edge/trunk/HW/Verilog/mux2.v =================================================================== --- edge/trunk/HW/Verilog/mux2.v (nonexistent) +++ edge/trunk/HW/Verilog/mux2.v (revision 2) @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////// +// // +// 2x1 Multiplixer // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// General purpose 2x1 multiplixer // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module mux2 +#(parameter N=32) +( + input[N-1:0] in1, + input[N-1:0] in2, + input s, + output [N-1:0] out +); + +assign out = (s)? in2 : in1; + +endmodule
edge/trunk/HW/Verilog/mux2.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/shifter_right_logical.v =================================================================== --- edge/trunk/HW/Verilog/shifter_right_logical.v (nonexistent) +++ edge/trunk/HW/Verilog/shifter_right_logical.v (revision 2) @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////// +// // +// Shift right logical for Edge Core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Shift right logical for Edge Core // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module shifter_right_logical +# +( + parameter N=32, SA=5 +) +( + input[N-1:0] in, + input[4:0] shamt, + output[N-1:0] out +); + +assign out = in >> shamt; + +endmodule Index: edge/trunk/HW/Verilog/reset_logic.v =================================================================== --- edge/trunk/HW/Verilog/reset_logic.v (nonexistent) +++ edge/trunk/HW/Verilog/reset_logic.v (revision 2) @@ -0,0 +1,74 @@ +////////////////////////////////////////////////////////////////// +// // +// Reset logic for Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Handling reset logic for Edge core jump to PC = 0 // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module reset_logic +# +( + parameter RESET_AFTER = 1 // Produce 0 signal after #RESET_AFTER clock cycles +) +( + input reset_interrupt, + input clk, + output reset +); + +reg[1:0] counter = 0; +reg res_buffer = 1; + +always @(posedge clk) +begin + /* Reset after specified clock cycles */ + /*counter = counter + 1; + if(counter == RESET_AFTER + 1) + res_buffer = 0; + */ + //res_buffer = 0; + + /* Only reset when reset button/signal pushed */ + if(reset_interrupt == 0) + res_buffer = 0; + else if(reset_interrupt == 1) + res_buffer = 1; + +end + +assign reset = res_buffer; + +endmodule Index: edge/trunk/HW/Verilog/mux_WBResult.v =================================================================== --- edge/trunk/HW/Verilog/mux_WBResult.v (nonexistent) +++ edge/trunk/HW/Verilog/mux_WBResult.v (revision 2) @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////// +// // +// Write back result select mux // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Multiplixer to choose from different result size // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +`define loadWord 3'b000 /* LW (normal load word) */ +`define loadSByte 3'b001 /* LB (load signed byte) */ +`define loadSHWord 3'b010 /* LH (load signed half word) */ +`define loadUByte 3'b011 /* LBU (load unsigned byte) */ +`define loadUHWord 3'b100 /* LHU (load unsgined half word) */ + +module mux_WBResult +# +( + parameter N=32 +) +( + input[N-1:0] Word, + input[N-1:0] SByte, + input[N-1:0] SHWord, + input[N-1:0] UByte, + input[N-1:0] UHWord, + input[2:0] s, + output reg[N-1:0] WBResult +); + +always @(*) + case (s) + `loadWord: WBResult = Word; + `loadSByte: WBResult = SByte; + `loadSHWord: WBResult = SHWord; + `loadUByte: WBResult = UByte; + `loadUHWord: WBResult = UHWord; + default: WBResult = Word; + endcase +endmodule Index: edge/trunk/HW/Verilog/id_ex_pipereg.v =================================================================== --- edge/trunk/HW/Verilog/id_ex_pipereg.v (nonexistent) +++ edge/trunk/HW/Verilog/id_ex_pipereg.v (revision 2) @@ -0,0 +1,448 @@ +////////////////////////////////////////////////////////////////// +// // +// ID/EX pipeline register // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Pipeline register lies between decode and execute stages // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module id_ex_pipereg +# +( + parameter N=32, + parameter M=5 +) +( + input clk, + input reset, + input en, + input[N-1:0] read_value1_in, + input[N-1:0] read_value2_in, + input[M-1:0] Rs_in, + input[M-1:0] Rt_in, + input[M-1:0] Rd_in, + input[N-1:0] SignImm_in, + input[N-1:0] PCplus4_in, + + input[N-1:0] IR_in, + input[5:0] opcode_in, + input RegWrite_in, + input[1:0] WBResultSelect_in, + input MemWrite_in, + input Branch_in, + input Jump_in, + input JumpR_in, + input[3:0] ALUControl_in, + input ALUSrcB_in, + input RegDst_in, + input UpperImm_in, + input[2:0] BHW_in, /* byte or halfword or word ? */ + input ALUComp_in, /* Complement the ALU output */ + input[1:0] Shift_type_in, + input ShiftAmtVar_in, + input Shifter_or_ALU_in, + input[1:0] MulDivRF_in, + input hiEN_in, + input loEN_in, + input link_in, + + /* Coprocessor0 and exceptions signals */ + input undefinedEx_in, + input breakEx_in, + input divbyZero_in, + input syscallEx_in, + + input[M-1:0] CP0_wa_in, + input[M-1:0] CP0_ra_in, + input[1:0] CP0_Inst_in, + input[N-1:0] CP0_dout_in, + input[N-1:0] CP0_din_in, + + /* Memory Reference size */ + input[1:0] MemRefSize_in, + + output[N-1:0] read_value1_out, + output[N-1:0] read_value2_out, + output[M-1:0] Rs_out, + output[M-1:0] Rt_out, + output[M-1:0] Rd_out, + output[N-1:0] SignImm_out, + output[N-1:0] PCplus4_out, + + output RegWrite_out, + output[1:0] WBResultSelect_out, + output MemWrite_out, + output Branch_out, + output Jump_out, + output JumpR_out, + output[3:0] ALUControl_out, + output ALUSrcB_out, + output RegDst_out, + output UpperImm_out, + output[2:0] BHW_out, /* byte or halfword or word ? */ + output ALUComp_out, + output[1:0] Shift_type_out, + output ShiftAmtVar_out, + output Shifter_or_ALU_out, + output[1:0] MulDivRF_out, + output hiEN_out, + output loEN_out, + output [5:0] opcode_out, + output[N-1:0] IR_out, + output link_out, + + /* Coprocessor0 and exceptions signals */ + output undefinedEx_out, + output breakEx_out, + output divbyZero_out, + output syscallEx_out, + + output[M-1:0] CP0_wa_out, + output[M-1:0] CP0_ra_out, + output[1:0] CP0_Inst_out, + output[N-1:0] CP0_dout_out, + output[N-1:0] CP0_din_out, + + output[1:0] MemRefSize_out + +); + +/* Instruction register */ +register IR +( + .clk(clk), .reset(reset), .en(en), + .d(IR_in), + .q(IR_out) +); + +/* Opcode */ +register #(6) +opcode +( + .clk(clk), .reset(reset), .en(en), + .d(opcode_in), + .q(opcode_out) +); + +/* data values registers */ +register rd1 +( + .clk(clk), .reset(reset), .en(en), + .d(read_value1_in), + .q(read_value1_out) +); + +register rd2 +( + .clk(clk), .reset(reset), .en(en), + .d(read_value2_in), + .q(read_value2_out) +); + +/* Rs, Rt and Rd addresses */ +register #(5) Rs +( + .clk(clk), .reset(reset), .en(en), + .d(Rs_in), + .q(Rs_out) +); + +register #(5) +Rt +( + .clk(clk), .reset(reset), .en(en), + .d(Rt_in), + .q(Rt_out) +); + +register #(5) +Rd +( + .clk(clk), .reset(reset), .en(en), + .d(Rd_in), + .q(Rd_out) +); + +/* Sign Immediate value */ +register sign_imm +( + .clk(clk), .reset(reset), .en(en), + .d(SignImm_in), + .q(SignImm_out) +); + +/* PC + 4 register */ +register PCplus4 +( + .clk(clk), .reset(reset), .en(en), + .d(PCplus4_in), + .q(PCplus4_out) +); + +/* Control Signal */ +register #(1) +RegWrite +( + .clk(clk), .reset(reset), .en(en), + .d(RegWrite_in), + .q(RegWrite_out) +); + +register #(2) +WBResultSelect +( + .clk(clk), .reset(reset), .en(en), + .d(WBResultSelect_in), + .q(WBResultSelect_out) +); + +register #(1) +MemWrite +( + .clk(clk), .reset(reset), .en(en), + .d(MemWrite_in), + .q(MemWrite_out) +); + +register #(1) +Branch +( + .clk(clk), .reset(reset), .en(en), + .d(Branch_in), + .q(Branch_out) +); + +register #(1) +Jump +( + .clk(clk), .reset(reset), .en(en), + .d(Jump_in), + .q(Jump_out) +); + +register #(1) +JumpR +( + .clk(clk), .reset(reset), .en(en), + .d(JumpR_in), + .q(JumpR_out) +); + +register #(1) +link +( + .clk(clk), .reset(reset), .en(en), + .d(link_in), + .q(link_out) +); + +register #(4) +ALUControl +( + .clk(clk), .reset(reset), .en(en), + .d(ALUControl_in), + .q(ALUControl_out) +); + +register #(1) +ALUSrcB +( + .clk(clk), .reset(reset), .en(en), + .d(ALUSrcB_in), + .q(ALUSrcB_out) +); + +register #(1) +RegDst +( + .clk(clk), .reset(reset), .en(en), + .d(RegDst_in), + .q(RegDst_out) +); + +register #(1) +UpperImm +( + .clk(clk), .reset(reset), .en(en), + .d(UpperImm_in), + .q(UpperImm_out) +); + +register #(3) +BHW +( + .clk(clk), .reset(reset), .en(en), + .d(BHW_in), + .q(BHW_out) +); + +register #(1) +ALUComp +( + .clk(clk), .reset(reset), .en(en), + .d(ALUComp_in), + .q(ALUComp_out) +); + +register #(2) +Shift_type +( + .clk(clk), .reset(reset), .en(en), + .d(Shift_type_in), + .q(Shift_type_out) +); + +register #(1) +ShiftAmtVar +( + .clk(clk), .reset(reset), .en(en), + .d(ShiftAmtVar_in), + .q(ShiftAmtVar_out) +); + +register #(1) +Shifter_or_ALU +( + .clk(clk), .reset(reset), .en(en), + .d(Shifter_or_ALU_in), + .q(Shifter_or_ALU_out) +); + +register #(2) +MulDivRF +( + .clk(clk), .reset(reset), .en(en), + .d(MulDivRF_in), + .q(MulDivRF_out) +); + +register #(1) +hiEN +( + .clk(clk), .reset(reset), .en(en), + .d(hiEN_in), + .q(hiEN_out) +); + +register #(1) +loEN +( + .clk(clk), .reset(reset), .en(en), + .d(loEN_in), + .q(loEN_out) +); + + +/* Coprocessor zero related */ +register #(1) +undefinedEx +( + .clk(clk), .reset(reset), .en(en), + .d(undefinedEx_in), + .q(undefinedEx_out) +); + +register #(1) +breakEx +( + .clk(clk), .reset(reset), .en(en), + .d(breakEx_in), + .q(breakEx_out) +); + +register #(1) +divbyZero +( + .clk(clk), .reset(reset), .en(en), + .d(divbyZero_in), + .q(divbyZero_out) +); + +register #(1) +syscallEx +( + .clk(clk), .reset(reset), .en(en), + .d(syscallEx_in), + .q(syscallEx_out) +); + +register #(5) +CP0_wa +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_wa_in), + .q(CP0_wa_out) +); + +register #(5) +CP0_ra +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_ra_in), + .q(CP0_ra_out) +); + +register #(2) +CP0_Inst +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_Inst_in), + .q(CP0_Inst_out) +); + +register CP0_dout +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_dout_in), + .q(CP0_dout_out) +); + +register CP0_din +( + .clk(clk), .reset(reset), .en(en), + .d(CP0_din_in), + .q(CP0_din_out) +); + +/* Memory referece sizes */ +register #(2) +MemRefSize +( + .clk(clk), .reset(reset), .en(en), + .d(MemRefSize_in), + .q(MemRefSize_out) +); + +endmodule
edge/trunk/HW/Verilog/id_ex_pipereg.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/alu_decoder.v =================================================================== --- edge/trunk/HW/Verilog/alu_decoder.v (nonexistent) +++ edge/trunk/HW/Verilog/alu_decoder.v (revision 2) @@ -0,0 +1,125 @@ +////////////////////////////////////////////////////////////////// +// // +// ALU decoder for Edge core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// ALU decoder decodes functions encoded in MIPS instruction // +// and sends out the appropriate command to ALU unit. // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +`define ADD_ALUOP 4'b0000 +`define SUB_ALUOP 4'b0001 +`define LOOK_FUNCT 4'b0010 +`define INVAL 4'b0011 +`define SLTI_ALUOP 4'b0100 +`define ANDI_ALUOP 4'b0101 +`define ORI_ALUOP 4'b0110 +`define XORI_ALUOP 4'b0111 +`define MUL_ALUOP 4'b1000 + +/* ALUControl output defines */ +`define ADD_ALUCTRL 4'b0010 +`define SUB_ALUCTRL 4'b0110 +`define AND_ALUCTRL 4'b0000 +`define OR_ALUCTRL 4'b0001 +`define SLT_ALUCTRL 4'b0111 +`define XOR_ALUCTRL 4'b0011 +`define NOR_ALUCTRL 4'b0100 +`define MUL_ALUCTRL 4'b1000 + +/* FUNCT defines INST[5:0] */ +`define SLL_FUNCT 6'b000000 // 0 +`define SRL_FUNCT 6'b000010 // 2 +`define SRA_FUNCT 6'b000011 // 3 +`define SLLV_FUNCT 6'b000100 // 4 +`define SRLV_FUNCT 6'b000110 // 6 +`define SRAV_FUNCT 6'b000111 // 7 +`define ADD_FUNCT 6'b100000 // 32 +`define ADDU_FUNCT 6'b100001 // 33 +`define SUB_FUNCT 6'b100010 // 34 +`define SUBU_FUNCT 6'b100011 // 35 +`define AND_FUNCT 6'b100100 // 36 +`define OR_FUNCT 6'b100101 // 37 +`define XOR_FUNCT 6'b100110 // 38 +`define NOR_FUNCT 6'b100111 // 39 +`define SLT_FUNCT 6'b101010 // 42 +`define SLTU_FUNCT 6'b101011 // 43 + +module alu_decoder +( + input[3:0] ALUop, + input[5:0] Funct, + output reg[3:0] ALUControl +); + +always @* +begin + + case(ALUop) + `ADD_ALUOP : ALUControl <= `ADD_ALUCTRL; + `SUB_ALUOP : ALUControl <= `SUB_ALUCTRL; + `SLTI_ALUOP: ALUControl <= `SLT_ALUCTRL; + `ANDI_ALUOP: ALUControl <= `AND_ALUCTRL; + `ORI_ALUOP : ALUControl <= `OR_ALUCTRL; + `XORI_ALUOP: ALUControl <= `XOR_ALUCTRL; + `MUL_ALUOP : ALUControl <= `MUL_ALUCTRL; + `LOOK_FUNCT: ALUControl <= funct_decode(Funct); + `INVAL : ALUControl <= 3'b000; /* (nop) Mapped to be add operation */ + default : ALUControl <= `ADD_ALUCTRL; + endcase +end + +function[3:0] funct_decode (input[5:0] funct); + case (funct) + `ADD_FUNCT, + `ADDU_FUNCT: + funct_decode = `ADD_ALUCTRL; + `SUB_FUNCT, + `SUBU_FUNCT: + funct_decode = `SUB_ALUCTRL; + `NOR_FUNCT, + `OR_FUNCT: + funct_decode = `OR_ALUCTRL; + `XOR_FUNCT: + funct_decode = `XOR_ALUCTRL; + `SLT_FUNCT, `SLTU_FUNCT: + funct_decode = `SLT_ALUCTRL; + default: + funct_decode = 5'b00000; + endcase + +endfunction + +endmodule
edge/trunk/HW/Verilog/alu_decoder.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/sign_extend.v =================================================================== --- edge/trunk/HW/Verilog/sign_extend.v (nonexistent) +++ edge/trunk/HW/Verilog/sign_extend.v (revision 2) @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////// +// // +// Sign extend unit for Edge Core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Sign extend unit for Edge Core // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module sign_extend +# +( + parameter N = 32, + parameter INSize = 16 +) +( + input[INSize-1:0] in, + output[N-1:0] out +); + +assign out = {{(N-INSize){in[INSize-1]}},in}; + +endmodule
edge/trunk/HW/Verilog/sign_extend.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Verilog/hazard_unit.v =================================================================== --- edge/trunk/HW/Verilog/hazard_unit.v (nonexistent) +++ edge/trunk/HW/Verilog/hazard_unit.v (revision 2) @@ -0,0 +1,164 @@ +////////////////////////////////////////////////////////////////// +// // +// Hazard unit for Edge Core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Hazard unit is responsible for detecting different pipline // +// hazards, and solving these hazards either by forwarding or // +// stalling the pipeline. // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module hazard_unit +#( + parameter N=32, M=5 +) +( + input CLK, + input[M-1:0] rsE, rtE, /* Source registers to ALU at EX stage */ + input[M-1:0] rsD, rtD, /* Source registers to ALU at EX stage */ + input[M-1:0] DestRegE, DestRegM, DestRegW, /* Destination registers at mem + and wb stages */ + input RegWriteE, RegWriteM, RegWriteW, /* Whether instruction writes to RF or + not */ + input loadE, /* load instruction */ + input MemWriteD, MemWriteE, /* Store */ + input[2:0] PCSrcM, /* PCplus4 or not */ + output reg[1:0] ForwardAE, ForwardBE, /* Forward signals to muxes at ALU +stages */ + output reg StallF, StallD, StallE, StallM, FlushE, StallW, /* Stall control + signals */ + output reg FlushD, FlushM, FlushF, + input StallDataMemory +); + +reg lwStall; +reg FlushControl; +reg stStall; /* Store stall right after load */ +reg RWHazard; /* Read and Write at the same clock cycle */ +reg[1:0] FetchCounter = 0; +reg FetchStall = 0; /* Two clock cycles for fetch to handle BRAM Read latency */ +reg[31:0] ClockCycleCount = 0; +wire FetchStallwire = (FetchStall == 1)? 1'b1 : 1'b0; +reg StoresInRowStall = 0; + +always @* +begin + lwStall = 1'b0; + stStall = 1'b0; + RWHazard = 1'b0; + ForwardAE = 2'b00; + ForwardBE = 2'b00; + StallF = 1'b0; + StallD = 1'b0; + FlushM = 1'b0; + FlushD = 1'b0; + FlushE = 1'b0; + FlushControl = 1'b0; + StoresInRowStall = 1'b0; + + if(rsE != 5'd0 && rsE == DestRegM && RegWriteM) + ForwardAE = 2'b10; + else if(rsE != 5'd0 && rsE == DestRegW && RegWriteW) + ForwardAE = 2'b01; + else + ForwardAE = 2'b00; + + if(rtE != 5'd0 && rtE == DestRegM && RegWriteM) + ForwardBE = 2'b10; + else if(rtE != 5'd0 && rtE == DestRegW && RegWriteW) + ForwardBE = 2'b01; + else + ForwardBE = 2'b00; + + /* load stall */ + if(loadE && (rsD == rtE || rtD == rtE)) + lwStall = 1'b1; + else + lwStall = 1'b0; + + /* Store stall */ + if + ( + (RegWriteM && MemWriteD && DestRegM == rtD) || + (RegWriteE + && MemWriteD && DestRegE == rtD) + ) + stStall = 1'b1; + + /* Stall for one clock cycle if there is two stores in row */ + if(MemWriteD && MemWriteE) + begin + StoresInRowStall = 1; + end + + /* Branch detected */ + if(PCSrcM != 3'b000) + FlushControl = 1'b1; + + /* Stall one clock cycle if there is w/r to a register in the same time */ + if( + (DestRegW == rsD || DestRegW == rtD) && + DestRegW !=0 && + StallDataMemory !=1 + ) + RWHazard = 1'b1; + + if( + (DestRegM == rsD || DestRegM == rtD) + && DestRegM !=0 && + MemWriteE && + StallDataMemory != 1 + ) + RWHazard = 1'b1; + + StallF = (lwStall == 1'b1 || stStall || RWHazard || + StoresInRowStall)? 1'b1:1'b0; + + StallD = (lwStall == 1'b1 || stStall || RWHazard || + StoresInRowStall)? 1'b1:1'b0; + + StallE = (lwStall == 1'b1)? 1'b1:1'b0; + StallM = (lwStall == 1'b1)? 1'b1:1'b0; + StallW = 0; + FlushF = (FlushControl); + FlushE = + (lwStall || stStall || FlushControl || StoresInRowStall || + RWHazard) ? 1'b1:1'b0; + FlushD = ((FlushControl == 1'b1))? 1'b1:1'b0; + FlushM = (FlushControl == 1'b1)? 1'b1:1'b0; + +end + +endmodule Index: edge/trunk/HW/Verilog/shifter_right_arithmetic.v =================================================================== --- edge/trunk/HW/Verilog/shifter_right_arithmetic.v (nonexistent) +++ edge/trunk/HW/Verilog/shifter_right_arithmetic.v (revision 2) @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////// +// // +// Shift right arithmetic unit for Edge Core // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Shift right arithmetic unit for Edge Core // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module shifter_right_arithmetic +# +( + parameter N=32, SA=5 +) +( + input[N-1:0] in, + input[4:0] shamt, + output[N-1:0] out +); + +assign out = (in >>> shamt); + +endmodule Index: edge/trunk/HW/Boards/Atlys/memory_system.v =================================================================== --- edge/trunk/HW/Boards/Atlys/memory_system.v (nonexistent) +++ edge/trunk/HW/Boards/Atlys/memory_system.v (revision 2) @@ -0,0 +1,268 @@ +////////////////////////////////////////////////////////////////// +// // +// Main memory system // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Main memory system is not only a wrapper to data memory // +// core, but also handling IO memory mapped operations. // +// The contents of this file are target dependent. // +// IO mapped regios, handles UART, Data memory stalling, timer// +// and LEDs. // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +`define BYTE_REF 2'b01 +`define HW_REF 2'b10 +`define W_REF 2'b11 + +`define NO_REF 2'b01 +`define LOADING 2'b10 +`define STORING 2'b11 + +module Memory_System +# +( + parameter N=32, H=16 +) +( + input clk, + + /* Processor Related */ + input[N-1:0] ProcessorAddress, /* Address coming from processor */ + input[N-1:0] WriteData, + input[1:0] MemRefSize, /* Size of data to reference (01->byte, 10->hw, +11->word) */ + input WE, + output[N-1:0] RD, + + output[N-1:0] UART_TX, + output UART_VALID, /* There is valid data to send */ + input[7:0] UART_CTRL, + input CP0_TimerIntMatch, + output StallBusy, + output[7:0] BRAM_dataOut, + output[7:0] LEDs, + output IO_TimerIntReset +); + +wire[31:0] addr; +wire[31:0] ReadValue; +reg[31:0] ReadData; +wire IODev; +wire RODATA_MEM; +wire[31:0] IOReadData; +wire IO_LED; +wire IO_TimerInt; +wire IO_TimerIntReset; + +reg[31:0] storeWord = 0; +wire[31:0] ClockCycleMax; +reg[31:0] ClockCycleLimit = 0; +wire BRAM_CLK; +wire[31:0] BRAM_ADDR; +wire[7:0] BRAM_DIN; +wire BRAM_WEA; + +wire[7:0] BRAM_DOUT; +wire[7:0] BRAM_RODATA_DOUT; +reg[31:0] BRAM_LOADADDR = 32'h800; +reg BRAM_LOAD_WEA = 0; +reg[7:0] BRAM_LOAD_DIN = 0; + +reg[31:0] BRAM_ProcessorADDR = 0; +reg BRAM_PROC_WEA = 0; +reg[7:0] BRAM_PROC_DIN = 0; + +reg GetByte = 0; +wire Stall; +reg fire; +reg[2:0] i = 0; +reg[2:0] loadCounter = 0; +reg[7:0] LED = 0; + +assign RD = (IODev)? IOReadData : ReadData; + +assign LEDs = LED; + +assign UART_VALID = ((ProcessorAddress == 32'hFFFF0100) && WE == 1)? + 1'b1 + : + 1'b0; + +assign IO_TimerIntReset = ((ProcessorAddress == 32'hFFFF010C) && WE == 1)? + 1'b1 + : + 1'b0; + +assign UART_TX = WriteData[7:0]; + +assign IODev = (ProcessorAddress >= 32'hFFFF0100)? 1'b1 : 1'b0; + +assign IO_LED = (ProcessorAddress == 32'hFFFF0108 && WE == 1)? 1'b1 : 1'b0; + +assign IO_TimerInt = (ProcessorAddress == 32'hFFFF010C)? 1'b1 : 1'b0; + +assign IOReadData = (ProcessorAddress == 32'hFFFF0104)? UART_CTRL : + (ProcessorAddress == 32'hFFFF010C)? CP0_TimerIntMatch : + 32'd0; + +assign StallBusy = ((i > 0 && i<=ClockCycleMax) )? 1'b1 : 1'b0; + +assign BRAM_CLK = clk; + +assign BRAM_ADDR = BRAM_ProcessorADDR; + +assign BRAM_DIN = BRAM_PROC_DIN; + +assign BRAM_WEA = BRAM_PROC_WEA; + +assign GetByte_out = GetByte; + +assign BRAM_dataOut = BRAM_DOUT; + +assign RODATA_MEM = + (ProcessorAddress >= 32'h00000800 && + ProcessorAddress <= 32'h00000BFF)? + 1'b1 : 1'b0; + +assign ClockCycleMax = (MemRefSize != 2'b00)? + //Loads + (WE == 0)? + (MemRefSize == `BYTE_REF)? 32'd2 : + (MemRefSize == `HW_REF)? 32'd4 : + (MemRefSize == `W_REF)? 32'd5 : + 32'd0 + : //Stores + (MemRefSize == `BYTE_REF)? 32'd1 : + (MemRefSize == `HW_REF)? 32'd2 : + (MemRefSize == `W_REF)? 32'd4 : + 32'd0 + : + 32'd0; + ; + +always @(posedge clk) + if(IO_LED) + LED = WriteData[7:0]; + +always @(negedge clk) +begin + + //RD = 0; + BRAM_PROC_WEA = 0; + //BRAM_ADDR = 0; + BRAM_PROC_DIN =0; + if(i == 0) + begin + storeWord = WriteData; + //ReadData = 0; + end + + if(MemRefSize != 2'b00) + begin + + if(i < ClockCycleMax) + begin + //StallBusy = 1; + i = i + 1; + + /* Loads */ + if(IODev != 1'b1) + begin + BRAM_ProcessorADDR = ProcessorAddress + i - 1; + //BRAM_DOUT = memory[BRAM_ADDR]; + ReadData = + (RODATA_MEM)? + (MemRefSize == `BYTE_REF)? + {24'd0, BRAM_RODATA_DOUT} + : + (MemRefSize == `HW_REF)? + {16'd0, BRAM_RODATA_DOUT, ReadData[15:8]} + : + (MemRefSize == `W_REF)? + {BRAM_RODATA_DOUT, ReadData[31:8]} + : + 32'd0 + + : /* Data memory */ + (MemRefSize == `BYTE_REF)? + {24'd0, BRAM_DOUT} + : + (MemRefSize == `HW_REF)? + {16'd0, BRAM_DOUT, ReadData[15:8]} + : + (MemRefSize == `W_REF)? + {BRAM_DOUT, ReadData[31:8]} + : + 32'd0; + end + + /* Stores to data memory */ + if(WE && IODev != 1'b1) + begin + BRAM_ProcessorADDR = ProcessorAddress + i - 1; + BRAM_PROC_DIN = storeWord[7:0]; + storeWord = {8'd0, storeWord[31:8]}; + BRAM_PROC_WEA = WE; + end + + end + + /* i >= ClockCycleMax */ + else + begin + i = 0; + end + + + end +end + +BRAM8x1024 data_memory +( + .clka(BRAM_CLK), // input clka + .wea(BRAM_WEA), // input [0 : 0] wea + .addra(BRAM_ADDR), // input [9 : 0] addra + .dina(BRAM_DIN), // input [7 : 0] dina + .douta(BRAM_DOUT) // output [7 : 0] douta +); + +ROM8x1024 rodata +( + .clka(BRAM_CLK), // input clka + .addra(BRAM_ADDR - 32'h00000800), // input [9 : 0] addra + .douta(BRAM_RODATA_DOUT) // output [7 : 0] douta +); + +endmodule Index: edge/trunk/HW/Boards/Atlys/edge_atlys_constraints.ucf =================================================================== --- edge/trunk/HW/Boards/Atlys/edge_atlys_constraints.ucf (nonexistent) +++ edge/trunk/HW/Boards/Atlys/edge_atlys_constraints.ucf (revision 2) @@ -0,0 +1,18 @@ +NET "LED<0>" LOC = U18; +NET "LED<2>" LOC = N14; +NET "LED<1>" LOC = M14; +NET "LED<3>" LOC = L14; +NET "LED<4>" LOC = M13; +NET "LED<5>" LOC = D4; +NET "LED<6>" LOC = P16; +NET "LED<7>" LOC = N12; + +NET "CLK" LOC = L15; +#NET "CLK" CLOCK_DEDICATED_ROUTE = FALSE; +#NET "RESET" CLOCK_DEDICATED_ROUTE = FALSE; + +# Reset # +NET "RESET" LOC="F5"; + +# USB UART Connector +NET "UART_TXD" LOC = "B16"; # Bank = 0, Pin name = IO_L66P_SCP1, Sch name = USBB-TXD; \ No newline at end of file Index: edge/trunk/HW/Boards/Atlys/edge_atlys_processor.v =================================================================== --- edge/trunk/HW/Boards/Atlys/edge_atlys_processor.v (nonexistent) +++ edge/trunk/HW/Boards/Atlys/edge_atlys_processor.v (revision 2) @@ -0,0 +1,172 @@ +////////////////////////////////////////////////////////////////// +// // +// Top level module for Edge project on Atlys board // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Top level module conatining Edge core, data memory, // +// instruction memory, uart controller and others to run on // +// Atyls board. // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module top_level +# +( + parameter N=32, + parameter M=5 +) +( + input CLK, + input RESET, + output[7:0] LED, + + output wire UART_TXD // UART send data +); + +wire CLK_2x; +wire CLK_50MHz; +wire reset; + +/* Insruction Memory in-out wires */ +wire[N-1:0] pc_toIMemory; +wire[N-1:0] instr_fromIMemory; + +/* Data Memory in-out wires */ +wire[N-1:0] Address_toDMemory, WriteData_toDMemory; +wire MemWrite_toDMemory; +wire[N-1:0] RD_fromDMemory; +wire UART_VALID; +wire[N-1:0] UART_TX; +wire UART_READY; +wire StallDataMemory; +wire[1:0] MemRefSize; +wire CP0_TimerIntMatch; +wire IO_TimerIntReset; + +reg[31:0] UART_CTRL = 0; +wire[31:0] UART_CTRL_TO_DMEM; + +clock_manager +# +( + .CLK_OUT(100000000/2) +) +clk_divider +( + .clk_in(CLK), + .clk_out(CLK_50MHz) +); + +clock_manager +#(.CLK_OUT(100000000/2) + ) +clk_div2x( + .clk_in(CLK), + .clk_out(CLK_2x) +); + +reset_logic reset_logic +( + .reset_interrupt(RESET), + .clk(CLK_50MHz), + .reset(reset) +); + + /* Instantiate the Unit Under Test (UUT) */ +Edge_Core Edge +( + .clk(CLK_50MHz), + .reset(reset), + .pc_toIMemory(pc_toIMemory), + .instr_fromIMemory(instr_fromIMemory), + + .Address_toDMemory(Address_toDMemory), + .WriteData_toDMemory(WriteData_toDMemory), + .MemWrite_toDMemory(MemWrite_toDMemory), + .MemRefSize(MemRefSize), + .RD_fromDMemory(RD_fromDMemory), + .StallDataMemory(StallDataMemory), + + .CP0_TimerIntMatch(CP0_TimerIntMatch), + .IO_TimerIntReset(IO_TimerIntReset) +); + + +/* Instantiate Insturction Memory */ +Instruction_Memory ins_mem +( + .CLK(CLK), + .reset(reset), + .address(pc_toIMemory), + .dout(instr_fromIMemory) +); + +/* Instantiate Data Memory */ +Memory_System mem_io +( + .clk(CLK_50MHz), + .ProcessorAddress(Address_toDMemory), + .WriteData(WriteData_toDMemory), + .WE(MemWrite_toDMemory), + .RD(RD_fromDMemory), + + .UART_TX(UART_TX), + .UART_VALID(UART_VALID), + .UART_CTRL(UART_CTRL_TO_DMEM), + .CP0_TimerIntMatch(CP0_TimerIntMatch), + .StallBusy(StallDataMemory), + .MemRefSize(MemRefSize), + .LEDs(LED), + .IO_TimerIntReset(IO_TimerIntReset) +); + +/* UART Transmitter to PC */ +UART_TX_CTRL serial_tty +( + .SEND(UART_VALID), + .DATA(UART_TX[7:0]), + .CLK(CLK_50MHz), + .READY(UART_READY), + .UART_TX(UART_TXD) +); + +always @(posedge CLK_50MHz) + if(UART_READY) + UART_CTRL[0] = 1; + else + UART_CTRL[0] = 0; + +assign UART_CTRL_TO_DMEM = UART_CTRL; + +endmodule Index: edge/trunk/HW/Boards/Atlys/UART_TX_CTRL.vhd =================================================================== --- edge/trunk/HW/Boards/Atlys/UART_TX_CTRL.vhd (nonexistent) +++ edge/trunk/HW/Boards/Atlys/UART_TX_CTRL.vhd (revision 2) @@ -0,0 +1,158 @@ +---------------------------------------------------------------------------- +-- UART_TX_CTRL.vhd -- UART Data Transfer Component +---------------------------------------------------------------------------- +-- Author: Sam Bobrowicz +-- Copyright 2011 Digilent, Inc. +---------------------------------------------------------------------------- +-- +---------------------------------------------------------------------------- +-- This component may be used to transfer data over a UART device. It will +-- serialize a byte of data and transmit it over a TXD line. The serialized +-- data has the following characteristics: +-- *115200 Baud Rate +-- *8 data bits, LSB first +-- *1 stop bit +-- *no parity +-- +-- Port Descriptions: +-- +-- SEND - Used to trigger a send operation. The upper layer logic should +-- set this signal high for a single clock cycle to trigger a +-- send. When this signal is set high DATA must be valid . Should +-- not be asserted unless READY is high. +-- DATA - The parallel data to be sent. Must be valid the clock cycle +-- that SEND has gone high. +-- CLK - A 100 MHz clock is expected +-- READY - This signal goes low once a send operation has begun and +-- remains low until it has completed and the module is ready to +-- send another byte. +-- UART_TX - This signal should be routed to the appropriate TX pin of the +-- external UART device. +-- +---------------------------------------------------------------------------- +-- +---------------------------------------------------------------------------- +-- Revision History: +-- 08/08/2011(SamB): Created using Xilinx Tools 13.2 +---------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.std_logic_unsigned.all; + +entity UART_TX_CTRL is + Port ( SEND : in STD_LOGIC; + DATA : in STD_LOGIC_VECTOR (7 downto 0); + CLK : in STD_LOGIC; + READY : out STD_LOGIC; + UART_TX : out STD_LOGIC); +end UART_TX_CTRL; + +architecture Behavioral of UART_TX_CTRL is + +type TX_STATE_TYPE is (RDY, LOAD_BIT, SEND_BIT); +-- 00101000101100 for 25 MHz 00000110110010 +constant BIT_TMR_MAX : std_logic_vector(13 downto 0) := "00000110110010"; +--434 = (round(50MHz / 115200)) - 1 +constant BIT_INDEX_MAX : natural := 10; + +--Counter that keeps track of the number of clock cycles the current bit has been held stable over the +--UART TX line. It is used to signal when the ne +signal bitTmr : std_logic_vector(13 downto 0) := (others => '0'); + +--combinatorial logic that goes high when bitTmr has counted to the proper value to ensure +--a 9600 baud rate +signal bitDone : std_logic; + +--Contains the index of the next bit in txData that needs to be transferred +signal bitIndex : natural; + +--a register that holds the current data being sent over the UART TX line +signal txBit : std_logic := '1'; + +--A register that contains the whole data packet to be sent, including start and stop bits. +signal txData : std_logic_vector(9 downto 0); + +signal txState : TX_STATE_TYPE := RDY; + +begin + +--Next state logic +next_txState_process : process (CLK) +begin + if (rising_edge(CLK)) then + case txState is + when RDY => + if (SEND = '1') then + txState <= LOAD_BIT; + end if; + when LOAD_BIT => + txState <= SEND_BIT; + when SEND_BIT => + if (bitDone = '1') then + if (bitIndex = BIT_INDEX_MAX) then + txState <= RDY; + else + txState <= LOAD_BIT; + end if; + end if; + when others=> --should never be reached + txState <= RDY; + end case; + end if; +end process; + +bit_timing_process : process (CLK) +begin + if (rising_edge(CLK)) then + if (txState = RDY) then + bitTmr <= (others => '0'); + else + if (bitDone = '1') then + bitTmr <= (others => '0'); + else + bitTmr <= bitTmr + 1; + end if; + end if; + end if; +end process; + +bitDone <= '1' when (bitTmr = BIT_TMR_MAX) else + '0'; + +bit_counting_process : process (CLK) +begin + if (rising_edge(CLK)) then + if (txState = RDY) then + bitIndex <= 0; + elsif (txState = LOAD_BIT) then + bitIndex <= bitIndex + 1; + end if; + end if; +end process; + +tx_data_latch_process : process (CLK) +begin + if (rising_edge(CLK)) then + if (SEND = '1') then + txData <= '1' & DATA & '0'; + end if; + end if; +end process; + +tx_bit_process : process (CLK) +begin + if (rising_edge(CLK)) then + if (txState = RDY) then + txBit <= '1'; + elsif (txState = LOAD_BIT) then + txBit <= txData(bitIndex); + end if; + end if; +end process; + +UART_TX <= txBit; +READY <= '1' when (txState = RDY) else + '0'; + +end Behavioral; + Index: edge/trunk/HW/Boards/Atlys/EdgeMemMap.bmm =================================================================== --- edge/trunk/HW/Boards/Atlys/EdgeMemMap.bmm (nonexistent) +++ edge/trunk/HW/Boards/Atlys/EdgeMemMap.bmm (revision 2) @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////// +// // +// Memory map for Edge project // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Memory map for Edge project to map elf files to BRAMS on // +// Atlys board. +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +ADDRESS_SPACE text RAMB16 [0x00000000:0x000007FF] +BUS_BLOCK + +ins_mem/ROM/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[0].ram.r/s6_noinit.ram/SP.SIMPLE_PRIM18.ram [31:0] PLACED = X0Y8; +END_BUS_BLOCK; +END_ADDRESS_SPACE; + +ADDRESS_SPACE rodata RAMB8 [0x00000800:0x00000BFF] +BUS_BLOCK + +mem_io/rodata/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[0].ram.r/s6_noinit.ram/SP.SIMPLE_PRIM9.ram [7:0] LOC = X1Y12; +END_BUS_BLOCK; +END_ADDRESS_SPACE; Index: edge/trunk/HW/Boards/Atlys/instruction_memory.v =================================================================== --- edge/trunk/HW/Boards/Atlys/instruction_memory.v (nonexistent) +++ edge/trunk/HW/Boards/Atlys/instruction_memory.v (revision 2) @@ -0,0 +1,64 @@ +////////////////////////////////////////////////////////////////// +// // +// Instruction memory system // +// // +// This file is part of the Edge project // +// http://www.opencores.org/project,edge // +// // +// Description // +// Instruction memory system is a wrapper for an IP core // +// or unit to be used as memory to embed MIPS instructions. // +// The contents of this file are target dependent. // +// // +// Author(s): // +// - Hesham AL-Matary, heshamelmatary@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2014 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +module Instruction_Memory +( + input CLK, + input[31:0] address, + output[31:0] dout, + input reset +); + +wire[31:0] addr; +wire[31:0] BRAM_ADDR; + +assign addr = ((address) & 32'hFFFFFFFC)/4 ; +assign BRAM_ADDR = (addr <= 512)? addr : 0; + +ROM32x512 ROM +( + .clka(CLK), // input clka + .addra(BRAM_ADDR), // input [9 : 0] addra + .douta(dout) // output [31 : 0] douta +); + +endmodule
edge/trunk/HW/Boards/Atlys/instruction_memory.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: edge/trunk/HW/Boards/Atlys/edge_atlys.bit =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: edge/trunk/HW/Boards/Atlys/edge_atlys.bit =================================================================== --- edge/trunk/HW/Boards/Atlys/edge_atlys.bit (nonexistent) +++ edge/trunk/HW/Boards/Atlys/edge_atlys.bit (revision 2)
edge/trunk/HW/Boards/Atlys/edge_atlys.bit Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.