URL
https://opencores.org/ocsvn/qrisc32/qrisc32/trunk
Subversion Repositories qrisc32
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/qrisc32/trunk/package.sv
0,0 → 1,308
////////////////////////////////////////////////////////////////////////////////////////////// |
// Project Qrisc32 is risc cpu implementation, purpose is studying |
// Digital System Design course at Kyoung Hee University during my PhD earning |
// Copyright (C) 2010 Vinogradov Viacheslav |
// |
// This library 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 library 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 library; if not, write to the Free Software |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
// |
// |
////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
`ifdef RISC_PACK_DEF |
`else |
`define RISC_PACK_DEF |
|
interface avalon_port; |
logic[31:0] address_r;//address |
logic[31:0] data_r;//data is read |
logic[31:0] data_w;//data to write |
logic rd,wr,wait_req;//read, write and wait request signals |
endinterface |
|
package risc_pack; |
typedef struct packed{ |
bit[31:0] val_r1;//value of register src1 |
bit[31:0] val_r2;//value of register src2 |
bit[31:0] val_dst;//value of register dst |
|
bit[4:0] src_r2;//indicate number of src2 register |
bit[4:0] src_r1;//indicate number of src1 register |
bit[4:0] dst_r;//indicate number of dest register |
|
//add to src2 |
bit[3:0] incr_r2;//0 +1 or -1, +2,-2, +4, -4 |
bit incr_r2_enable;// |
|
// |
bit write_reg;//indicate write to RF(addres in dst_r, value in dst_v) |
//load store operations, if both bit is zero then bypass MEM stage |
bit read_mem;//indicate read from memory(addres in src1+src2) |
bit write_mem;//indicate write to memory(addres in src1+src2, value in dst) |
// |
|
//if alu and shift operations are zeros then bypass EX stage |
//alu operations |
bit and_op;//AND |
bit or_op;// OR |
bit xor_op;//XOR |
bit add_op;//+ |
bit mul_op;// |
bit cmp_op;//compare operation |
|
bit ldrf_op;//conditional load |
//shifter operations |
bit shl_op;//shift left |
bit shr_op;//shift right |
//jmp operations |
//old pc in value in val_r1 |
//offset to pc value in val_r2 |
//new pc value in val_dst |
//types of jump |
//indicate to calc new address of PC |
bit jmpunc; |
bit jmpz; |
bit jmpnz; |
bit jmpc; |
bit jmpnc; |
|
}pipe_struct; |
|
//typedef enum logic[3:0]{ |
//operations |
parameter[3:0] LDR=4'd0;//,//LDR Rdst,[Rsrc1],-+Rsrc2 |
//[31:28]LDR_op |
//[27:26] type of LDR op |
//0- Rdst= Rsrc1 |
//1-Rdst[31:16] = code[20:5] LDRH Rx,0x1234 |
//2-Rdst[15:0] = code[20:5] LDRL Rx,0x5678 |
//3- Rdst=[Rsrc1+offset] |
//[25] |
//0 - offset = code[24:10](signed) |
//1 - offset = Rsrc2(signed) |
//[24:22] |
//000 Rsrc2=Rsrc2 |
//001 Rsrc2=Rsrc2+1 |
//010 Rsrc2=Rsrc2+2 |
//011 Rsrc2=Rsrc2+4 |
//100 Rsrc2=Rsrc2 |
//101 Rsrc2=Rsrc2-1 |
//110 Rsrc2=Rsrc2-2 |
//111 Rsrc2=Rsrc2-4 |
//[14:10] src2 |
//[9:5]src1 |
//[4:0]dst |
parameter[3:0] |
STR=4'd1;//,//STR Rdst,[Rsrc1],-+Rsrc2 |
//[31:28]STR_op |
//[27:26] type of STORE op |
//3- [Rsrc1+offset]=Rdst |
//[25] |
//0 - offset = code[24:10](signed) |
//1 - offset = Rsrc2(signed) |
//[24:23] |
//000 Rsrc2=Rsrc2 |
//001 Rsrc2=Rsrc2+1 |
//010 Rsrc2=Rsrc2+2 |
//011 Rsrc2=Rsrc2+4 |
//100 Rsrc2=Rsrc2 |
//101 Rsrc2=Rsrc2-1 |
//110 Rsrc2=Rsrc2-2 |
//111 Rsrc2=Rsrc2-4 |
//[14:10] src2 |
//[9:5]src1 |
//[4:0]dst |
parameter[3:0] |
JMPUNC=4'd2;//,//unconditional jump |
//[31:28] jump |
//[27:26] type of jumps |
//0 - jmp pc[25:0]=code[25:0] |
//1 - jmp pc=pc+offset(relaitive jump) jmpr R2(jmpr R2+4) |
//2 - call pc=pc+offset, Rdst=pc callr R0,0xXXXXXXX,R1+4 or callr R0,R1+4 |
//3 - ret pc=Rdst ret Rx or ret Rx,Ry+-0,1,2,4 |
//[25] |
//0 - offset = code[24:10](signed) |
//1 - offset = Rsrc2(signed) |
//[24:23] |
//000 Rsrc2=Rsrc2 |
//001 Rsrc2=Rsrc2+1 |
//010 Rsrc2=Rsrc2+2 |
//011 Rsrc2=Rsrc2+4 |
//100 Rsrc2=Rsrc2 |
//101 Rsrc2=Rsrc2-1 |
//110 Rsrc2=Rsrc2-2 |
//111 Rsrc2=Rsrc2-4 |
//[14:10] src2 |
//[9:5]src1 |
//[4:0]dst |
parameter[3:0] |
JMPF=4'd3;//,//conditional jumps |
//[31:28] jump |
//[27:26] type of jumps |
//0 - jmpz pc=pc+offset |
//1 - jmpnz pc=pc+offset |
//2 - jmpc pc=pc+offset |
//3 - jmpnc pc=pc+offset |
//[25] |
//0 - offset = code[24:10](signed) |
//1 - offset = Rsrc2(signed) |
//[24:22] |
//000 Rsrc2=Rsrc2 |
//001 Rsrc2=Rsrc2+1 |
//010 Rsrc2=Rsrc2+2 |
//011 Rsrc2=Rsrc2+4 |
//100 Rsrc2=Rsrc2 |
//101 Rsrc2=Rsrc2-1 |
//110 Rsrc2=Rsrc2-2 |
//111 Rsrc2=Rsrc2-4 |
//[14:10] src2 |
//[9:5]src1 |
//[4:0]dst |
|
parameter[3:0] |
ALU=4'd4;// AND, OR, XOR, |
// ADD, MUL, |
// SHR, SHL |
//[31:28]ALU_op |
//[27:25] type of op |
//0- AND |
//1- OR |
//2- XOR |
//3- ADD |
//4- MUL |
//5-shift Rsrc1 left by Rscr2 ...0 MSB->C flag |
//6-shift Rsrc1 right by Rscr2 ...0 LSB ->C flag |
//7-CMP compare, |
//[24:23] |
//000 Rsrc2=Rsrc2 |
//001 Rsrc2=Rsrc2+1 |
//010 Rsrc2=Rsrc2+2 |
//011 Rsrc2=Rsrc2+4 |
//100 Rsrc2=Rsrc2 |
//101 Rsrc2=Rsrc2-1 |
//110 Rsrc2=Rsrc2-2 |
//111 Rsrc2=Rsrc2-4 |
//[14:10] src2 |
//[9:5]src1 |
//[4:0]dst |
//} OPCODE; |
parameter[3:0] |
LDRF=4'd5;//,//LDRF Rdst,Rsrc1,-+Rsrc2 |
//[31:28]LDRF_op |
//[27:26] type of LDRF op |
//0-LDRZ Rdst=Rsrc1 if z=1, otherwise Rdst=Rsrc2 |
//1-LDRNZ Rdst=Rsrc1 if z=0, otherwise Rdst=Rsrc2 |
//2-LDRC Rdst=Rsrc1 if c=1, otherwise Rdst=Rsrc2 |
//3-LDRNC Rdst=Rsrc1 if c=0, otherwise Rdst=Rsrc2 |
//[24:22] |
//000 Rsrc2=Rsrc2 |
//001 Rsrc2=Rsrc2+1 |
//010 Rsrc2=Rsrc2+2 |
//011 Rsrc2=Rsrc2+4 |
//100 Rsrc2=Rsrc2 |
//101 Rsrc2=Rsrc2-1 |
//110 Rsrc2=Rsrc2-2 |
//111 Rsrc2=Rsrc2-4 |
//[14:10] src2 |
//[9:5]src1 |
//[4:0]dst |
|
|
parameter[4+1:0] NOP = {32'h0}; |
//ldr |
parameter[4+1:0] LDRR = {LDR,2'b00}; |
parameter[4+6:0] LDRH = {LDR,7'b01_0_000_0}; |
parameter[4+6:0] LDRL = {LDR,7'b10_0_000_0}; |
parameter[4+1:0] LDRP = {LDR,2'b11}; |
|
//str |
parameter[4+1:0] STRP ={STR,2'b11}; |
|
//alu |
parameter[4+2:0] AND ={ALU,3'd0}; |
parameter[4+2:0] OR ={ALU,3'd1}; |
parameter[4+2:0] XOR ={ALU,3'd2}; |
parameter[4+2:0] ADD ={ALU,3'd3}; |
parameter[4+2:0] MUL ={ALU,3'd4}; |
parameter[4+2:0] SHL ={ALU,3'd5}; |
parameter[4+2:0] SHR ={ALU,3'd6}; |
parameter[4+2:0] CMP ={ALU,3'd7}; |
|
//jmp |
parameter[4+1:0] JMP ={JMPUNC,2'd0}; |
parameter[4+1:0] JMPR ={JMPUNC,2'd1}; |
parameter[4+1:0] CALL ={JMPUNC,2'd2}; |
parameter[4+1:0] RET ={JMPUNC,2'd3}; |
|
parameter[4+1:0] JMPZ ={JMPF,2'd0}; |
parameter[4+1:0] JMPNZ ={JMPF,2'd1}; |
parameter[4+1:0] JMPC ={JMPF,2'd2}; |
parameter[4+1:0] JMPNC ={JMPF,2'd3}; |
|
|
parameter[4+2:0] LDRZ ={LDRF,2'd0,1'b0}; |
parameter[4+2:0] LDRNZ ={LDRF,2'd1,1'b0}; |
parameter[4+2:0] LDRC ={LDRF,2'd2,1'b0}; |
parameter[4+2:0] LDRNC ={LDRF,2'd3,1'b0}; |
|
//common |
parameter[0:0] OFFSET_CODE =1'b0; |
parameter[0:0] OFFSET_R =1'b1; |
|
parameter[2:0] INCR_0 =3'b000; |
parameter[2:0] DECR_0 =3'b000; |
parameter[2:0] INCR_1 =3'b001; |
parameter[2:0] INCR_2 =3'b010; |
parameter[2:0] INCR_4 =3'b011; |
parameter[2:0] DECR_1 =3'b101; |
parameter[2:0] DECR_2 =3'b110; |
parameter[2:0] DECR_4 =3'b111; |
|
parameter[4:0] R0 =5'd0; |
parameter[4:0] R1 =5'd1; |
parameter[4:0] R2 =5'd2; |
parameter[4:0] R3 =5'd3; |
parameter[4:0] R4 =5'd4; |
parameter[4:0] R5 =5'd5; |
parameter[4:0] R6 =5'd6; |
parameter[4:0] R7 =5'd7; |
parameter[4:0] R8 =5'd8; |
parameter[4:0] R9 =5'd9; |
parameter[4:0] R10 =5'd10; |
parameter[4:0] R11 =5'd11; |
parameter[4:0] R12 =5'd12; |
parameter[4:0] R13 =5'd13; |
parameter[4:0] R14 =5'd14; |
parameter[4:0] R15 =5'd15; |
parameter[4:0] R16 =5'd16; |
parameter[4:0] R17 =5'd17; |
parameter[4:0] R18 =5'd18; |
parameter[4:0] R19 =5'd19; |
parameter[4:0] R20 =5'd20; |
parameter[4:0] R21 =5'd21; |
parameter[4:0] R22 =5'd22; |
parameter[4:0] R23 =5'd23; |
parameter[4:0] R24 =5'd24; |
parameter[4:0] R25 =5'd25; |
parameter[4:0] R26 =5'd26; |
parameter[4:0] R27 =5'd27; |
parameter[4:0] R28 =5'd28; |
parameter[4:0] R29 =5'd29; |
parameter[4:0] R30 =5'd30; |
parameter[4:0] R31 =5'd31; |
|
endpackage |
|
`endif |
/qrisc32/trunk/qrisc32_TB.sv
0,0 → 1,553
////////////////////////////////////////////////////////////////////////////////////////////// |
// Project Qrisc32 is risc cpu implementation, purpose is studying |
// Digital System Design course at Kyoung Hee University during my PhD earning |
// Copyright (C) 2010 Vinogradov Viacheslav |
// |
// This library 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 library 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 library; if not, write to the Free Software |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
// |
// |
////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
`timescale 1ns / 1ns |
|
module qrisc32_tb; |
//Parameters declaration: |
import risc_pack::*; |
|
//Internal signals declarations: |
bit reset,clk; |
//I data |
logic[31:0] idata; |
logic[31:0] iaddr; |
logic ird; |
logic ireq; |
|
//D read |
logic[31:0] rdata; |
logic[31:0] raddr; |
logic rrd; |
logic rreq=0; |
|
//D write |
logic[31:0] wdata; |
logic[31:0] waddr; |
logic wwr; |
logic wreq=0; |
logic Istop_active,Dstop_active; |
bit Istop_enable,Dstop_enable; |
bit verbose; |
|
//emulates Instruction ram |
mem Iram( |
.clk(clk), |
.add_r(iaddr), |
.add_w(32'h0), |
.data_w(32'h0), |
.rd(ird), |
.wr(1'b0), |
.data_r(idata), |
.req(ireq), |
.stop_enable(Istop_enable), |
.stop_active(Istop_active), |
.verbose(verbose) |
); |
defparam Iram.size=256; |
defparam Iram.adr_limit=93; |
|
//emulates Data ram |
mem Dram( |
.clk(clk), |
.add_r(raddr), |
.add_w(waddr), |
.data_w(wdata), |
.rd(rrd), |
.wr(wwr), |
.data_r(rdata), |
.req(), |
.stop_enable(Dstop_enable), |
.stop_active(Dstop_active), |
.verbose(verbose) |
); |
defparam Dram.size=10; |
defparam Dram.adr_limit=10; |
|
// Unit Under Test port map |
qrisc32 UUT( |
.reset(reset), |
.clk(clk), |
//avalon master port only for reading instructions |
.avm_instructions_data(idata), |
.avm_instructions_addr(iaddr), |
.avm_instructions_rd(ird), |
.avm_instructions_wait_req(ireq), |
|
//avalon master port only for reading data |
.avm_datar_data(rdata), |
.avm_datar_addr(raddr), |
.avm_datar_rd(rrd), |
.avm_datar_wait_req(rreq), |
|
//avalon master port only for writing data |
.avm_dataw_data(wdata), |
.avm_dataw_addr(waddr), |
.avm_dataw_wr(wwr), |
.avm_dataw_wait_req(wreq), |
.verbose(verbose) |
); |
|
int address; |
bit signed[14:0] jmpr_label0,jmpr_label1; |
bit [25:0] ilabel,jlabel,inclabel,jmp_label1; |
|
function void loadIram; |
input[31:0] data; |
begin |
Iram.sram[address] = data; |
address=address+1; |
end |
endfunction |
|
task load_buble_sort; |
/*buble algorithm |
R0=mem[00],R1=mem[04],R2=mem[08],R3=mem[c],R4=mem[10] |
R5=mem[14],R6=mem[18],R7=mem[1c],R8=mem[20],R9=mem[24] |
R10=R0; |
R11=R0;//minimum |
if R1<R11 |
R11=R1 |
if R2<R11 |
R11=R2 |
if R3<R11 |
R11=R3 |
if R4<R11 |
R11=R4 |
if R5<R11 |
R11=R5 |
if R6<R11 |
R11=R6 |
if R7<R11 |
R11=R7 |
if R8<R11 |
R11=R8 |
if R9<R11 |
R11=R9 |
mem[0]=R11; |
|
for (i = 36; i > 0; i-=4)//36,32,28,24,20,16,12,8,4 |
{ |
if R0>R10 |
R10=R0 |
if R1>R10 |
R10=R1 |
if R2>R10 |
R10=R2 |
if R3>R10 |
R10=R3 |
if R4>R10 |
R10=R4 |
if R5>R10 |
R10=R5 |
if R6>R10 |
R10=R6 |
if R7>R10 |
R10=R7 |
if R8>R10 |
R10=R8 |
if R9>R10 |
R10=R9 |
|
mem[i]=R10; |
|
//substitute maximum by minimum |
if R10=R0 |
R0=R11 |
if R10=R1 |
R1=R11 |
if R10=R2 |
R2=R11 |
if R10=R3 |
R3=R11 |
if R10=R4 |
R4=R11 |
if R10=R5 |
R5=R11 |
if R10=R6 |
R6=R11 |
if R10=R7 |
R7=R11 |
if R10=R8 |
R8=R11 |
if R10=R9 |
R9=R11 |
|
}*/ |
//loading instructions |
address=0; |
//verbose=1; |
//Istop_enable=1; |
|
loadIram({LDRH,16'h0000,R12});//R12 is 36 |
loadIram({XOR,DECR_0,7'h0,R13,R13,R13});//R13 is 0 |
loadIram({LDRH,16'hFFFF,R14});//R14 is -4 |
loadIram({LDRL,16'h0024,R12});//R12 is 36 |
|
loadIram({LDRP,OFFSET_CODE,15'd00,R13,R0});//ldr R0,[R13+0] |
loadIram({LDRP,OFFSET_CODE,15'd04,R13,R1});//ldr R1,[R13+4] |
loadIram({LDRP,OFFSET_CODE,15'd08,R13,R2});//ldr R2,[R13+8] |
loadIram({LDRP,OFFSET_CODE,15'd12,R13,R3});//ldr R3,[R13+12] |
loadIram({LDRP,OFFSET_CODE,15'd16,R13,R4});//ldr R4,[R13+16] |
|
loadIram({LDRP,OFFSET_CODE,15'd20,R13,R5});//ldr R5,[R13+20] |
loadIram({LDRP,OFFSET_CODE,15'd24,R13,R6});//ldr R6,[R13+24] |
loadIram({LDRP,OFFSET_CODE,15'd28,R13,R7});//ldr R7,[R13+28] |
loadIram({LDRP,OFFSET_CODE,15'd32,R13,R8});//ldr R8,[R13+32] |
loadIram({LDRP,OFFSET_CODE,15'd36,R13,R9});//ldr R9,[R13+36] |
|
loadIram({LDRL,-16'd4,R14});//R14 is -4 |
|
//search for minimum |
loadIram({CMP,INCR_0,7'h0,R0,R1,R1}); |
loadIram({LDRC,INCR_0,7'h0,R0,R1,R16}); |
|
loadIram({CMP,INCR_0,7'h0,R3,R2,R2}); |
loadIram({LDRC,INCR_0,7'h0,R3,R2,R17}); |
|
loadIram({CMP,INCR_0,7'h0,R5,R4,R4}); |
loadIram({LDRC,INCR_0,7'h0,R5,R4,R18}); |
|
loadIram({CMP,INCR_0,7'h0,R7,R6,R6}); |
loadIram({LDRC,INCR_0,7'h0,R7,R6,R19}); |
|
loadIram({CMP,INCR_0,7'h0,R9,R8,R8}); |
loadIram({LDRC,INCR_0,7'h0,R9,R8,R20}); |
|
loadIram({CMP,INCR_0,7'h0,R17,R16,R16}); |
loadIram({LDRC,INCR_0,7'h0,R17,R16,R21}); |
|
loadIram({CMP,INCR_0,7'h0,R19,R18,R18}); |
loadIram({LDRC,INCR_0,7'h0,R19,R18,R22}); |
|
loadIram({CMP,INCR_0,7'h0,R21,R20,R20}); |
loadIram({LDRC,INCR_0,7'h0,R21,R20,R23}); |
loadIram({NOP}); |
|
loadIram({CMP,INCR_0,7'h0,R23,R22,R22}); |
loadIram({LDRC,INCR_0,7'h0,R23,R22,R11}); |
|
loadIram({NOP}); |
//minimum write |
loadIram({STRP,OFFSET_CODE,15'd0,R13,R11});//str R10,[R13+0] |
|
// |
//search for maximum |
loadIram({CMP,INCR_0,7'h0,R0,R1,R1}); |
loadIram({LDRNC,INCR_0,7'h0,R0,R1,R16}); |
|
loadIram({CMP,INCR_0,7'h0,R3,R2,R2}); |
jmpr_label0=4*address; |
loadIram({LDRNC,INCR_0,7'h0,R3,R2,R17}); |
|
loadIram({CMP,INCR_0,7'h0,R5,R4,R4}); |
loadIram({LDRNC,INCR_0,7'h0,R5,R4,R18}); |
|
loadIram({CMP,INCR_0,7'h0,R7,R6,R6}); |
loadIram({LDRNC,INCR_0,7'h0,R7,R6,R19}); |
|
loadIram({CMP,INCR_0,7'h0,R9,R8,R8}); |
loadIram({LDRNC,INCR_0,7'h0,R9,R8,R20}); |
|
loadIram({CMP,INCR_0,7'h0,R17,R16,R16}); |
loadIram({LDRNC,INCR_0,7'h0,R17,R16,R21}); |
|
loadIram({CMP,INCR_0,7'h0,R19,R18,R18}); |
loadIram({LDRNC,INCR_0,7'h0,R19,R18,R22}); |
|
loadIram({CMP,INCR_0,7'h0,R21,R20,R20}); |
loadIram({LDRNC,INCR_0,7'h0,R21,R20,R23}); |
loadIram({NOP}); |
|
loadIram({CMP,INCR_0,7'h0,R23,R22,R22}); |
loadIram({LDRNC,INCR_0,7'h0,R23,R22,R10}); |
loadIram({NOP}); |
|
loadIram({STRP,OFFSET_CODE,15'd0,R12,R10});//str R10,[R12+0] |
|
loadIram({ADD,DECR_0,7'h0,R14,R12,R12});//R12 = R12 + R12( -4) |
|
loadIram({CMP,INCR_0,7'h0,R0,R10,R10}); |
loadIram({LDRZ,INCR_0,7'h0,R0,R11,R0}); |
loadIram({CMP,INCR_0,7'h0,R1,R10,R10}); |
loadIram({LDRZ,INCR_0,7'h0,R1,R11,R1}); |
loadIram({CMP,INCR_0,7'h0,R2,R10,R10}); |
loadIram({LDRZ,INCR_0,7'h0,R2,R11,R2}); |
loadIram({CMP,INCR_0,7'h0,R3,R10,R10}); |
loadIram({LDRZ,INCR_0,7'h0,R3,R11,R3}); |
loadIram({CMP,INCR_0,7'h0,R4,R10,R10}); |
loadIram({LDRZ,INCR_0,7'h0,R4,R11,R4}); |
loadIram({CMP,INCR_0,7'h0,R5,R10,R10}); |
loadIram({LDRZ,INCR_0,7'h0,R5,R11,R5}); |
loadIram({CMP,INCR_0,7'h0,R6,R10,R10}); |
loadIram({LDRZ,INCR_0,7'h0,R6,R11,R6}); |
loadIram({CMP,INCR_0,7'h0,R7,R10,R10}); |
loadIram({LDRZ,INCR_0,7'h0,R7,R11,R7}); |
loadIram({CMP,INCR_0,7'h0,R8,R10,R10}); |
loadIram({LDRZ,INCR_0,7'h0,R8,R11,R8}); |
loadIram({CMP,INCR_0,7'h0,R9,R10,R10}); |
loadIram({LDRZ,INCR_0,7'h0,R9,R11,R9}); |
|
loadIram({CMP,INCR_0,7'h0,R13,R12,R12});//cmp R12 with R13(0) |
|
jmpr_label1=jmpr_label0-4*address-8; |
loadIram({JMPNZ,OFFSET_CODE,jmpr_label1,10'h0}); |
loadIram({LDRR,DECR_0,7'h0,R11,R11,R10});//R10 =R11 |
|
loadIram({CMP,INCR_0,7'h0,R0,R1,R1}); |
loadIram({LDRNC,INCR_0,7'h0,R0,R1,R16}); |
loadIram({CMP,INCR_0,7'h0,R3,R2,R2}); |
|
|
endtask; |
|
|
task load_shell_sort_mdf; |
/*new algorithm |
for(inc = 20;inc>0;inc=inc/2)//20, 8 and 4 (5,2,1) |
{ |
for (i = inc; i < 40; i+=4)//0..4..8..c and etc |
{ |
temp = a[i]; |
for (j = i; (j >= inc) && (a[j-inc] > temp); j =j-inc) |
{ |
a[j] = a[j-inc]; |
} |
a[j] = temp; |
} |
}*/ |
//--------------------- reverse(709) random(714) sorted(516) |
//loading instructions |
address=0; |
loadIram({LDRH,16'h0000,R5});//R5 inc = 5 |
loadIram({LDRH,16'h0000,R8});//R8 =1 |
loadIram({LDRH,16'h0000,R9});//R9 =2 |
loadIram({LDRH,16'h0000,R10});//R10 is 4 |
loadIram({LDRH,16'h0000,R12});//R12 is 40 |
loadIram({LDRH,16'hFFFF,R13});//R13 is mask 0xffff_ffff |
loadIram({LDRH,16'h0000,R14});//R14 is 3 |
|
loadIram({LDRL,16'h0005,R5});//R5 inc = 5 |
loadIram({LDRL,16'h0001,R8});//R8 =1 |
loadIram({LDRL,16'h0002,R9});//R9 =2 |
loadIram({LDRL,16'h0004,R10});//R10 is 4 |
loadIram({LDRL,16'h0028,R12});//R12 is 40 |
loadIram({LDRL,16'hFFFF,R13});//R13 is mask 0xffff_ffff |
loadIram({LDRL,16'h0003,R14});//R14 is 3 |
|
//R5 - inc |
//R6 - -inc |
//R7 - j-inc |
//R4 - i |
//R3 - J |
//for (inc... |
inclabel = 4*address; |
jmpr_label0 = 4*address; |
loadIram({SHL,INCR_0,7'h0,R9,R5,R5});//R5 = R5<<R9( R5<<2) |
|
jmpr_label1=1000*4;//out of code |
loadIram({JMPZ,OFFSET_CODE,jmpr_label1,10'h0});//R5>0? |
|
loadIram({XOR,DECR_0,7'h0,R13,R5,R6});//R6 = R5 xor R13 |
loadIram({LDRR,DECR_0,7'h0,R5,R5,R4});//i(R4)=inc (R5) |
loadIram({ADD,DECR_0,7'h0,R8,R6,R6});//R6 = R6 + R8( +1) |
loadIram({SHR,INCR_0,7'h0,R14,R5,R5});//R5 = R5>>R14( R5>>3)) |
|
loadIram({CMP,INCR_0,7'h0,R12,R4,R4});//compare R4 with R12(i == 40) if 0 then reached maximum-> stop |
ilabel=4*address; |
|
jmpr_label1=jmpr_label0-4*address-8; |
loadIram({JMPZ,OFFSET_CODE,jmpr_label1,10'h0});//if =40 then goto inc |
|
//temp - r1 |
loadIram({LDRP,OFFSET_CODE,15'd0,R4,R1});//ldr R1,[R4] |
|
//for (j = i;.. |
loadIram({LDRR,DECR_0,7'h0,R4,R4,R3});//j(R3)=i(R4) |
loadIram({ADD,DECR_0,7'h0,R4,R6,R7});//R7 = R4+R6=(i)j-inc |
|
loadIram({CMP,INCR_0,7'h0,R5,R3,R3});//cmp R3 j with R5 inc |
jlabel=4*address; |
//a[j-inc] - r0 |
loadIram({LDRP,OFFSET_CODE,15'd0,R7,R0});//ldrp R0,[R7] |
|
jmpr_label1=13*4; |
loadIram({JMPC,OFFSET_CODE,jmpr_label1,10'h0});//c=1 then R3 j < R5 inc |
loadIram({NOP});loadIram({NOP});loadIram({NOP}); |
|
//a[j-inc] > temp? |
loadIram({CMP,INCR_0,7'h0,R1,R0,R0});//cmp R0 a[j-inc] with R1 temp |
|
jmpr_label1=8*4; |
loadIram({JMPC,OFFSET_CODE,jmpr_label1,10'h0});//c=1 then R0>R1 |
loadIram({NOP});loadIram({NOP});loadIram({NOP});loadIram({NOP}); |
|
loadIram({JMP,jlabel});//goto next cycle of J |
loadIram({LDRR,DECR_0,7'h0,R7,R7,R3});//j=j-inc, R3=R7 |
//a[j] = a[j-inc]; |
loadIram({STRP,OFFSET_CODE,15'd0,R3,R0});//str R0,[R3+0] |
loadIram({ADD,DECR_0,7'h0,R3,R6,R7});//R7 = R3+R6=j-inc |
loadIram({CMP,INCR_0,7'h0,R5,R3,R3});//cmp R3 j with R5 inc |
|
// |
loadIram({JMP,ilabel});//goto next cycle of i |
loadIram({ADD,DECR_0,7'h0,R10,R4,R4});//R4=R4+R10...i+=4 |
//a[j] = temp; |
loadIram({STRP,OFFSET_CODE,15'd0,R3,R1});//str R3,[R7+0] |
loadIram({CMP,INCR_0,7'h0,R12,R4,R4});//compare R4 with R12(i == 40) if 0 then reached maximum-> stop |
loadIram({NOP}); |
endtask; |
|
|
task shell_first; |
|
//old |
// for (i = 0; i < 36; i+=4) { |
// temp = a[i+4]; |
// for (j = i; (j >= 0) && (a[j] > temp); j -= 4)a[j+4] = a[j]; |
// a[j+4] = temp; |
|
//loading instructions |
address=0; |
loadIram({LDRH,16'h0000,R10});//R10 is 4 |
loadIram({LDRH,16'hffff,R11});//R11 is -4 |
loadIram({LDRH,16'h0000,R12});//R12 is 36 |
jmp_label1 = 4*address+4*8; |
loadIram({JMP,jmp_label1});//goto entry point |
|
loadIram({XOR,INCR_0,7'h0,R4,R4,R4});//i base of data |
loadIram({LDRL,16'h0004,R10});//R10 is 4 |
loadIram({LDRL,16'hFFFC,R11});//R11 is -4 |
loadIram({LDRL,16'h0024,R12});//R12 is 36 |
//R4 is i=0 base of data |
//R7 is J |
|
//end of main cycle |
jmpr_label0=4*address; |
jmpr_label1=4*address+32*8; |
|
loadIram({JMPZ,OFFSET_CODE,jmpr_label1,10'h0});//goto to out of main cycle |
loadIram({LDRR,DECR_0,7'h0,R5,R4,R7});//R7 = R4 ->R7 is J |
//a[j+4] = temp; |
loadIram({STRP,OFFSET_CODE,15'd4,R7,R0});//str R0,[R7+4] |
//main cycle here (I)------------------------------------------------- |
//entry point |
//temp=a[i], R0 is temp |
loadIram({LDRP,OFFSET_CODE,15'd0,R4,R15});//ldr R0,[R4+0] |
|
//check j <0 |
loadIram({XOR,DECR_0,7'h0,R7,R11,R2});//compare R7 with -4 |
loadIram({LDRP,OFFSET_CODE,15'd4,R4,R0});//ldr R0,[R4+4] |
// |
jmp_label1=4*address; |
jmpr_label1=jmpr_label0-4*address-8; |
loadIram({JMPZ,OFFSET_CODE,jmpr_label1,10'h0});//Z=1 when J<0 goto end of main cycle a[j+4] = temp; |
//i+=4 |
loadIram({ADD,DECR_0,7'h0,R10,R4,R4});//R4 = R4+4 |
loadIram({LDRR,DECR_0,7'h0,R15,R15,R1});//R1=R15 |
//check i =36? |
loadIram({XOR,INCR_0,7'h0,R12,R4,R2});//R2=R4^R12(i xor 36) if 0 then reached maximum-> stop |
//a[j] read |
loadIram({LDRP,OFFSET_CODE,-15'd4,R7,R15});//ldr R15,[R7-4] |
|
//compare R1(a[j]) with R0(temp) |
loadIram({CMP,INCR_0,7'h0,R0,R1,R2}); |
jmpr_label1=jmpr_label0-4*address-8; |
loadIram({JMPC,OFFSET_CODE,jmpr_label1,10'h0});//c=1 then R1<=R0 - (a[j] > temp) is false goto end of subcycle (A[j+4]=temp) |
loadIram({NOP});loadIram({NOP});loadIram({NOP}); |
//check i =36? |
loadIram({XOR,INCR_0,7'h0,R12,R4,R2});//R2=R4^R12(i xor 36) if 0 then reached maximum-> stop |
|
loadIram({JMP,jmp_label1});//goto subcycle |
//j-=4 |
loadIram({ADD,DECR_0,7'h0,R7,R11,R7});//R7 = R7-4 |
//i-=4 |
loadIram({ADD,DECR_0,7'h0,R11,R4,R4});//R4 = R4-4 |
//a[j+4] = a[j](R1); |
loadIram({STRP,OFFSET_CODE,15'd8,R7,R1});//str R1,[R7+4] A[j+4]=temp |
loadIram({XOR,DECR_0,7'h0,R7,R11,R2});//compare R7 with -4 |
|
endtask; |
|
task load_unsorted_data(bit[1:0] kind); |
//loading unsorted data in Dram |
for(int i=0;i<10;i++) |
Dram.sram[i]=(kind==0)? 10-i: //reverse unsorted |
(kind==1)? 100+$random%100://randomly unsorted |
i+1; //already sorted |
endtask; |
|
task start; |
reset=1; |
$display("Programm size is %d Words",address); |
#100; |
reset=0; |
#1us; |
@(posedge Istop_active); |
$display("Sort finished"); |
$display("Cycles for sorting -->%0d<--",cycles); |
endtask; |
|
initial |
begin |
Istop_enable=0; |
Dstop_enable=0; |
verbose=0; |
for(int i=0;i<3;i++) |
begin |
$display("------------------Start round %d------------------",i); |
load_unsorted_data(i); |
$display("Load buble sort..."); |
load_buble_sort; |
start; |
|
load_unsorted_data(i); |
$display("Load shell modified..."); |
load_shell_sort_mdf; |
start; |
|
load_unsorted_data(i); |
$display("Load shell first..."); |
shell_first; |
start; |
|
end |
$finish; |
end |
|
initial |
begin |
clk=0; |
forever #10 clk<=!clk; |
end |
|
int cycles; |
|
always@(posedge clk or posedge reset) |
if(reset) |
cycles=0; |
else |
cycles=cycles+1; |
|
endmodule |
/qrisc32/trunk/risc_report.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
qrisc32/trunk/risc_report.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: qrisc32/trunk/mem.sv
===================================================================
--- qrisc32/trunk/mem.sv (nonexistent)
+++ qrisc32/trunk/mem.sv (revision 2)
@@ -0,0 +1,93 @@
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Project Qrisc32 is risc cpu implementation, purpose is studying
+// Digital System Design course at Kyoung Hee University during my PhD earning
+// Copyright (C) 2010 Vinogradov Viacheslav
+//
+// This library 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 library 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 library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+//
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+module mem#(size=256,adr_limit=64)(
+ input clk,
+ input[31:0] add_r,add_w,data_w,
+ input rd,wr,
+ output bit[31:0] data_r,
+ output req
+
+ ,input stop_enable//=1 will stop on each problem(non align access and out of adr access)
+ ,output bit stop_active//=1 will indicate about stop signal
+ ,input verbose
+ );
+
+ bit[31:0] sram[size-1:0];
+
+ assign req = 1'b0;
+ wire[$bits(size)-1:0]add_r_word =add_r[31:2];
+ wire[$bits(size)-1:0]add_w_word =add_w[31:2];
+
+ always@(posedge clk)
+ begin
+ stop_active=0;
+ if(wr)
+ begin
+ sram[add_w_word]<=data_w;
+ if(verbose)
+ $display(".................................[%m] write at address %08x with data %08x",add_w,data_w);
+ end
+ data_r <= sram[add_r_word];
+
+ if(rd)
+ begin
+ if(verbose)
+ $display(".................................[%m] read at address %08x with data %08x",add_r,sram[add_r_word]);
+ end
+
+ if(wr && add_w>adr_limit*4)
+ begin
+ if(verbose)
+ $display(".................................[%m] write out of limit address %08x",add_w);
+ stop_active=1;
+ if(stop_enable)$stop;
+ end
+
+ if(rd && add_r>adr_limit*4)
+ begin
+ if(verbose)
+ $display(".................................[%m] read out of limit address %08x",add_r);
+ if(stop_enable)$stop;
+ stop_active=1;
+ end
+
+ if(add_r[1:0]!=0 && rd)
+ begin
+ if(verbose)
+ $display(".................................[%m] read by non align address %08x",add_r);
+ if(stop_enable)$stop;
+ stop_active=1;
+ end
+
+ if(add_w[1:0]!=0 && wr)
+ begin
+ if(verbose)
+ $display(".................................[%m] write by non align address %08x",add_w);
+ if(stop_enable)$stop;
+ stop_active=1;
+ end
+ end
+
+endmodule
Index: qrisc32/trunk/qrisc32_EX.sv
===================================================================
--- qrisc32/trunk/qrisc32_EX.sv (nonexistent)
+++ qrisc32/trunk/qrisc32_EX.sv (revision 2)
@@ -0,0 +1,141 @@
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Project Qrisc32 is risc cpu implementation, purpose is studying
+// Digital System Design course at Kyoung Hee University during my PhD earning
+// Copyright (C) 2010 Vinogradov Viacheslav
+//
+// This library 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 library 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 library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+//
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+
+import risc_pack::*;
+
+module qrisc32_EX(
+ input clk,reset,pipe_stall,
+ input pipe_struct pipe_ex_in,
+ output pipe_struct pipe_ex_out,
+
+ output bit new_address_valid,//to mem stage
+ output bit[31:0] new_address//to mem stage
+ );
+
+import risc_pack::*;
+
+ bit flagZ_w, flagC_w;
+ bit flagZ, flagC;
+ wire signed[31:0] r2 = pipe_ex_in.val_r2;
+ wire signed[3:0] inc_r2 = pipe_ex_in.incr_r2;
+ wire signed[31:0] r2_add = r2 + inc_r2;
+
+ wire[32:0] summ_result = pipe_ex_in.val_r1 + pipe_ex_in.val_r2;
+
+ pipe_struct pipe_ex_out_w;
+
+ always_comb
+ begin
+ pipe_ex_out_w=pipe_ex_in;
+ flagZ_w=0;
+ flagC_w=0;
+
+ if(pipe_ex_in.ldrf_op)
+ begin
+ if( (pipe_ex_in.jmpz && flagZ)
+ || (pipe_ex_in.jmpnz && ~flagZ)
+ || (pipe_ex_in.jmpc && flagC)
+ || (pipe_ex_in.jmpnc && ~flagC)
+ )
+ pipe_ex_out_w.val_dst=pipe_ex_in.val_r1;
+ else
+ pipe_ex_out_w.val_dst=pipe_ex_in.val_r2;
+ end
+ else if(pipe_ex_in.and_op)
+ begin
+ pipe_ex_out_w.val_dst=pipe_ex_in.val_r1 & pipe_ex_in.val_r2;
+ flagC_w=0;
+ flagZ_w=(pipe_ex_out_w.val_dst==0)?1:0;
+ end
+ else if(pipe_ex_in.or_op)
+ begin
+ pipe_ex_out_w.val_dst=pipe_ex_in.val_r1 | pipe_ex_in.val_r2;
+ flagC_w=0;
+ flagZ_w=(pipe_ex_out_w.val_dst==0)?1:0;
+ end
+ else if(pipe_ex_in.xor_op)
+ begin
+ pipe_ex_out_w.val_dst=pipe_ex_in.val_r1 ^ pipe_ex_in.val_r2;
+ flagC_w=0;
+ flagZ_w=(pipe_ex_out_w.val_dst==0)?1:0;
+ end
+ else if(pipe_ex_in.add_op//simple addition operation
+ || pipe_ex_in.jmpunc //jump unconditional calculate address = R1+R2(offset)
+ //jump conditional calculate address = R1+R2(offset) and check flags
+ || pipe_ex_in.jmpz || pipe_ex_in.jmpnz || pipe_ex_in.jmpc || pipe_ex_in.jmpnc)
+ begin
+ {flagC_w,pipe_ex_out_w.val_dst}=summ_result;
+ flagZ_w=(pipe_ex_out_w.val_dst==0)?1:0;
+ end
+ else if(pipe_ex_in.mul_op)
+ begin
+ {flagC_w,pipe_ex_out_w.val_dst}=pipe_ex_in.val_r1 * pipe_ex_in.val_r2;
+ flagZ_w=(pipe_ex_out_w.val_dst==0)?1:0;
+ end
+ else if(pipe_ex_in.shl_op)
+ begin
+ {flagC_w,pipe_ex_out_w.val_dst}=pipe_ex_in.val_r1 << pipe_ex_in.val_r2;
+ flagZ_w=(pipe_ex_out_w.val_dst==0)?1:0;
+ end
+ else if(pipe_ex_in.shr_op)
+ begin
+ {pipe_ex_out_w.val_dst,flagC_w}={pipe_ex_in.val_r1,1'b0 }>> pipe_ex_in.val_r2;
+ flagZ_w=(pipe_ex_out_w.val_dst==0)?1:0;
+ end
+ else if(pipe_ex_in.cmp_op)
+ begin
+ flagZ_w=(pipe_ex_out_w.val_r1==pipe_ex_out_w.val_r2)?1:0;
+ flagC_w=(pipe_ex_out_w.val_r1>=pipe_ex_out_w.val_r2)?0:1;
+ end
+ pipe_ex_out_w.val_r2 = (pipe_ex_out_w.incr_r2_enable)?r2_add:pipe_ex_out_w.val_r2;
+ end
+
+ always@(posedge clk)
+ begin
+ flagZ<=
+ (pipe_ex_in.and_op | pipe_ex_in.or_op | pipe_ex_in.xor_op | pipe_ex_in.add_op
+ | pipe_ex_in.mul_op | pipe_ex_in.shl_op | pipe_ex_in.shr_op | pipe_ex_in.cmp_op)?flagZ_w:flagZ;
+
+ flagC<=
+ (pipe_ex_in.and_op | pipe_ex_in.or_op | pipe_ex_in.xor_op | pipe_ex_in.add_op
+ | pipe_ex_in.mul_op | pipe_ex_in.shl_op | pipe_ex_in.shr_op | pipe_ex_in.cmp_op)?flagC_w:flagC;
+
+ if(pipe_ex_in.jmpunc || (pipe_ex_in.jmpz & flagZ) ||(pipe_ex_in.jmpnz & !flagZ)||
+ (pipe_ex_in.jmpc & flagC) ||(pipe_ex_in.jmpnc & !flagC) )
+ begin
+ new_address_valid<=~pipe_ex_in.ldrf_op;
+ new_address<=pipe_ex_out_w.val_dst;
+ end
+ else
+ new_address_valid<=0;
+
+ if(~pipe_stall)
+ begin
+ pipe_ex_out<=pipe_ex_out_w;
+ if(pipe_ex_in.read_mem| pipe_ex_in.write_mem)
+ pipe_ex_out.val_r1<=summ_result;//address for accessing
+ end
+
+ end
+
+endmodule
Index: qrisc32/trunk/qrisc32_ID.sv
===================================================================
--- qrisc32/trunk/qrisc32_ID.sv (nonexistent)
+++ qrisc32/trunk/qrisc32_ID.sv (revision 2)
@@ -0,0 +1,437 @@
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Project Qrisc32 is risc cpu implementation, purpose is studying
+// Digital System Design course at Kyoung Hee University during my PhD earning
+// Copyright (C) 2010 Vinogradov Viacheslav
+//
+// This library 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 library 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 library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+//
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+
+import risc_pack::*;
+
+module qrisc32_ID(
+ input clk,reset,
+ input [31:0] instruction,
+ input [31:0] pc,
+
+ input pipe_stall,//feed back from MEM stage
+ input pipe_struct pipe_wb_mem,//for memory read
+ input pipe_struct pipe_wb_ex,//for R2 register and ALU operations only
+
+ output pipe_struct pipe_id_out,
+ input verbose
+ );
+
+ import risc_pack::*;
+
+ bit[31:0] rf[31:0];//32 regs width is 32
+ bit[31:0] offset_w;
+ pipe_struct pipe_id_out_w;
+ bit[31:0] nop_counter;
+ bit[31:0] jmp_counter;
+ bit[31:0] alu_counter;
+ bit[31:0] oth_counter;
+
+ //comb part
+ always_comb
+ begin
+ pipe_id_out_w.dst_r = instruction[04:00];
+ pipe_id_out_w.src_r1 = instruction[09:05];
+ pipe_id_out_w.src_r2 = instruction[14:10];
+ pipe_id_out_w.incr_r2 = 0;
+ pipe_id_out_w.incr_r2_enable = 1;
+
+
+ pipe_id_out_w.read_mem = 0;
+ pipe_id_out_w.write_mem = 0;
+ pipe_id_out_w.write_reg = 0;
+
+ pipe_id_out_w.mul_op = 0;
+ pipe_id_out_w.add_op = 0;
+ pipe_id_out_w.or_op = 0;
+ pipe_id_out_w.and_op = 0;
+ pipe_id_out_w.xor_op = 0;
+ pipe_id_out_w.shl_op = 0;
+ pipe_id_out_w.shr_op = 0;
+ pipe_id_out_w.cmp_op = 0;
+ pipe_id_out_w.ldrf_op = 0;
+
+
+ pipe_id_out_w.jmpunc = 0;
+ pipe_id_out_w.jmpz = 0;
+ pipe_id_out_w.jmpnz = 0;
+ pipe_id_out_w.jmpc = 0;
+ pipe_id_out_w.jmpnc = 0;
+
+ pipe_id_out_w.val_r1 = (pipe_wb_mem.write_reg && pipe_wb_mem.dst_r==pipe_id_out_w.src_r1)?
+ pipe_wb_mem.val_dst://forward from memory read
+ //(pipe_wb_mem.incr_r2_enable && pipe_wb_mem.src_r2==pipe_id_out_w.src_r1)?
+ //pipe_wb_mem.val_r2://forward from mem stage R2 register
+ (pipe_wb_ex.write_reg && pipe_wb_ex.dst_r==pipe_id_out_w.src_r1)?
+ pipe_wb_ex.val_dst://forward from execution stage DST register
+ (pipe_wb_ex.incr_r2_enable && pipe_wb_ex.src_r2==pipe_id_out_w.src_r1)?
+ pipe_wb_ex.val_r2://forward from execution stage R2 register
+ rf[pipe_id_out_w.src_r1];//otherwise from register file
+
+ pipe_id_out_w.val_r2 = (pipe_wb_mem.write_reg && pipe_wb_mem.dst_r==pipe_id_out_w.src_r2)?
+ pipe_wb_mem.val_dst://forward from memory read
+ //(pipe_wb_mem.incr_r2_enable && pipe_wb_mem.src_r2==pipe_id_out_w.src_r2)?
+ //pipe_wb_mem.val_r2://forward from mem stage R2 register
+ (pipe_wb_ex.write_reg && pipe_wb_ex.dst_r==pipe_id_out_w.src_r2)?
+ pipe_wb_ex.val_dst://forward from execution stage DST register
+ (pipe_wb_ex.incr_r2_enable && pipe_wb_ex.src_r2==pipe_id_out_w.src_r2)?
+ pipe_wb_ex.val_r2://forward from execution stage R2 register
+ rf[pipe_id_out_w.src_r2];//otherwise from register file
+
+
+ pipe_id_out_w.val_dst = (pipe_wb_mem.write_reg && pipe_wb_mem.dst_r==pipe_id_out_w.dst_r)?
+ pipe_wb_mem.val_dst://forward from memory read
+ //(pipe_wb_mem.incr_r2_enable && pipe_wb_mem.src_r2==pipe_id_out_w.dst_r)?
+ //pipe_wb_mem.val_r2://forward from mem stage R2 register
+ (pipe_wb_ex.write_reg && pipe_wb_ex.dst_r==pipe_id_out_w.dst_r)?
+ pipe_wb_ex.val_dst://forward from execution stage DST register
+ (pipe_wb_ex.incr_r2_enable && pipe_wb_ex.src_r2==pipe_id_out_w.dst_r)?
+ pipe_wb_ex.val_r2://forward from execution stage R2 register
+ rf[pipe_id_out_w.dst_r];//otherwise from register file
+
+ offset_w = (instruction[25])?pipe_id_out_w.val_r2:{{17{instruction[24]}},instruction[24:10]};//17 bit sign + 15 bit offset
+
+ case(instruction[24:22])
+ 0:begin pipe_id_out_w.incr_r2=4'd0;pipe_id_out_w.incr_r2_enable = 0;end
+ 1:pipe_id_out_w.incr_r2=4'd1;
+ 2:pipe_id_out_w.incr_r2=4'd2;
+ 3:pipe_id_out_w.incr_r2=4'd4;
+ 4:begin pipe_id_out_w.incr_r2=4'd0;pipe_id_out_w.incr_r2_enable = 0;end
+ 5:pipe_id_out_w.incr_r2=-4'd1;
+ 6:pipe_id_out_w.incr_r2=-4'd2;
+ 7:pipe_id_out_w.incr_r2=-4'd4;
+ endcase
+
+ case(instruction[31:28])
+ //load and store
+ LDR:
+ case(instruction[27:26])
+ 2'b00:
+ begin
+ pipe_id_out_w.write_reg = (pipe_id_out_w.dst_r!=pipe_id_out_w.src_r1)?1:0;//write from reg src1 to reg dst
+ //pipe_id_out_w.incr_r2_enable = pipe_id_out_w.write_reg;
+ pipe_id_out_w.val_dst = pipe_id_out_w.val_r1;
+ end
+ 2'b01:
+ begin
+ pipe_id_out_w.val_dst[31:16] = instruction[20:5];
+ pipe_id_out_w.write_reg = 1;//write from reg src1 to reg dst
+ pipe_id_out_w.incr_r2_enable = 0;
+ end
+ 2'b10:
+ begin
+ pipe_id_out_w.val_dst[15:0] = instruction[20:5];
+ pipe_id_out_w.write_reg = 1;//write from reg src1 to reg dst
+ pipe_id_out_w.incr_r2_enable = 0;
+ end
+ 2'b11:
+ begin
+ pipe_id_out_w.read_mem = 1;//read from mem by Rscr2+Rsrc1 and then write to register
+ pipe_id_out_w.write_reg = 1;//write from reg src1 to reg dst
+ pipe_id_out_w.incr_r2_enable = instruction[25];
+ pipe_id_out_w.val_r2 = offset_w;
+ end
+ endcase
+
+ STR:
+ case(instruction[27:26])
+ //2'b11:
+ default:
+ begin
+ pipe_id_out_w.write_mem = 1;//write Rdst to mem by Rscr2+Rsrc1
+ pipe_id_out_w.val_r2 = offset_w;
+ pipe_id_out_w.incr_r2_enable = instruction[25];
+ end
+ endcase
+
+ //jumps
+ JMPUNC:
+ case(instruction[27:26])
+ 2'b00:
+ begin
+ pipe_id_out_w.val_r1 =instruction[25:0];
+ pipe_id_out_w.val_r2 ='0;//no offset
+ pipe_id_out_w.incr_r2_enable = 0;
+ pipe_id_out_w.jmpunc = 1;
+ end
+ 2'b01://relative jump
+ begin
+ pipe_id_out_w.val_r1 =pc;
+ pipe_id_out_w.val_r2 =offset_w;//offset
+ pipe_id_out_w.incr_r2_enable = instruction[25];
+ pipe_id_out_w.jmpunc = 1;
+ end
+ 2'b10://call
+ begin
+ pipe_id_out_w.val_r1 =pc;
+ pipe_id_out_w.val_r2 =offset_w;//offset
+ pipe_id_out_w.val_dst =pc;//return address
+ pipe_id_out_w.incr_r2_enable = instruction[25];
+ pipe_id_out_w.jmpunc = 1;
+ pipe_id_out_w.write_reg = 1;
+ end
+ 2'b11://ret
+ begin
+ pipe_id_out_w.val_r1 =pipe_id_out_w.val_dst;
+ pipe_id_out_w.val_r2 ='0;//offset
+ pipe_id_out_w.incr_r2_enable = instruction[25];
+ pipe_id_out_w.jmpunc = 1;
+ end
+ endcase
+
+ JMPF:
+ case(instruction[27:26])
+ 2'b00://jmpz
+ begin
+ pipe_id_out_w.val_r1 =pc;
+ pipe_id_out_w.val_r2 =offset_w;//offset
+ pipe_id_out_w.incr_r2_enable = instruction[25];
+ pipe_id_out_w.jmpz = 1;
+ end
+ 2'b01://jmpnz
+ begin
+ pipe_id_out_w.val_r1 =pc;
+ pipe_id_out_w.val_r2 =offset_w;//offset
+ pipe_id_out_w.incr_r2_enable = instruction[25];
+ pipe_id_out_w.jmpnz = 1;
+ end
+ 2'b10://jmpc
+ begin
+ pipe_id_out_w.val_r1 =pc;
+ pipe_id_out_w.val_r2 =offset_w;//offset
+ pipe_id_out_w.incr_r2_enable = instruction[25];
+ pipe_id_out_w.jmpc = 1;
+ end
+ 2'b11://jmpnc
+ begin
+ pipe_id_out_w.val_r1 =pc;
+ pipe_id_out_w.val_r2 =offset_w;//offset
+ pipe_id_out_w.incr_r2_enable = instruction[25];
+ pipe_id_out_w.jmpnc = 1;
+ end
+ endcase
+
+ //Arithmetic
+ ALU:
+ case(instruction[27:25])
+ 3'd0:
+ begin
+ pipe_id_out_w.write_reg = 1;
+ pipe_id_out_w.and_op = 1;
+ end
+ 3'd1:
+ begin
+ pipe_id_out_w.write_reg = 1;
+ pipe_id_out_w.or_op = 1;
+ end
+ 3'd2:
+ begin
+ pipe_id_out_w.write_reg = 1;
+ pipe_id_out_w.xor_op = 1;
+ end
+ 3'd3:
+ begin
+ pipe_id_out_w.write_reg = 1;
+ pipe_id_out_w.add_op = 1;
+ end
+ 3'd4:
+ begin
+ pipe_id_out_w.write_reg = 1;
+ pipe_id_out_w.mul_op = 1;
+ end
+ 3'd5:
+ begin
+ pipe_id_out_w.write_reg = 1;
+ pipe_id_out_w.shl_op = 1;
+ end
+ 3'd6:
+ begin
+ pipe_id_out_w.write_reg = 1;
+ pipe_id_out_w.shr_op = 1;
+ end
+ //cmp_op =7
+ default:
+ begin
+ //pipe_id_out_w.write_reg = 0;
+ pipe_id_out_w.cmp_op = 1;
+ end
+ endcase
+
+ LDRF:
+ case(instruction[27:26])
+ 2'b00://ldrz
+ begin
+ pipe_id_out_w.jmpz = 1;
+ pipe_id_out_w.ldrf_op = 1;
+ pipe_id_out_w.write_reg = 1;
+ end
+ 2'b01://ldrnz
+ begin
+ pipe_id_out_w.jmpnz = 1;
+ pipe_id_out_w.ldrf_op = 1;
+ pipe_id_out_w.write_reg = 1;
+ end
+ 2'b10://ldrc
+ begin
+ pipe_id_out_w.ldrf_op = 1;
+ pipe_id_out_w.jmpc = 1;
+ pipe_id_out_w.write_reg = 1;
+ end
+ 2'b11://ldrnc
+ begin
+ pipe_id_out_w.ldrf_op = 1;
+ pipe_id_out_w.jmpnc = 1;
+ pipe_id_out_w.write_reg = 1;
+ end
+ endcase
+
+ default:
+ begin
+ pipe_id_out_w='0;
+ end
+ endcase
+ end
+
+ always@(posedge clk)// or posedge reset)
+ if(reset)
+ begin
+ pipe_id_out<='0;
+ for(int i=0;i<32;i++)
+ rf[i]<='0;
+ nop_counter<='0;
+ jmp_counter<='0;
+ alu_counter<='0;
+ oth_counter<='0;
+ end
+ else
+ begin
+ if(instruction==0)
+ nop_counter<=nop_counter+1;
+ else
+ if(instruction[31:28]==JMPUNC || instruction[31:28]==JMPF)
+ jmp_counter<=jmp_counter+1;
+ else
+ if(instruction[31:28]==ALU)
+ alu_counter<=alu_counter+1;
+ else
+ oth_counter<=oth_counter+1;
+
+ if(~pipe_stall)
+ pipe_id_out<=pipe_id_out_w;
+
+ if(pipe_wb_ex.write_reg)//from ex stage DST register
+ rf[pipe_wb_ex.dst_r]<=pipe_wb_ex.val_dst;
+
+ if(pipe_wb_ex.incr_r2_enable)//from ex stage R2 register
+ rf[pipe_wb_ex.src_r2]<=pipe_wb_ex.val_r2;
+
+ if(pipe_wb_mem.write_reg)//from memory read stage
+ rf[pipe_wb_mem.dst_r]<=pipe_wb_mem.val_dst;
+
+ //if(pipe_wb_mem.incr_r2_enable)//from mem stage R2 register
+ // rf[pipe_wb_mem.src_r2]<=pipe_wb_mem.val_r2;
+
+
+//synthesys translate_off
+ if(verbose)
+ begin
+ if(~pipe_stall)
+ begin
+ case(instruction[31:28])
+ //load and store
+ LDR:
+ case(instruction[27:26])
+ 2'b00:$display("LDR R%0d, R%0d, R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ 2'b01:$display("LDRH R%0d,0x%x",pipe_id_out_w.dst_r,instruction[20:5]);
+ 2'b10:$display("LDRL R%0d,0x%x",pipe_id_out_w.dst_r,instruction[20:5]);
+ 2'b11:$display("LDRP R%0d,[R%0d +%0d],R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,$signed(offset_w),pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ endcase
+
+ STR:
+ case(instruction[27:26])
+ default:$display("STR R%0d,[R%0d +%0d],R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,$signed(offset_w),pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ endcase
+
+ //jumps
+ JMPUNC:
+ case(instruction[27:26])
+ 2'b00:$display("JMP 0x%0x",instruction[25:0]);
+ 2'b01://relative jump
+ $display("JMPR PC 0x%0x + offset %0d",pc,$signed(offset_w));
+ 2'b10://call
+ $display("CALLR PC 0x%0x + offset %0d",pc,$signed(offset_w));
+ 2'b11://ret
+ $display("RET to 0x%0x",pipe_id_out_w.val_dst);
+ endcase
+
+ JMPF:
+ case(instruction[27:26])
+ 2'b00://jmpz
+ $display("JMPZ PC 0x%0x + offset %0d",pc,$signed(offset_w));
+ 2'b01://jmpnz
+ $display("JMPNZ PC 0x%0x + offset %0d",pc,$signed(offset_w));
+ 2'b10://jmpc
+ $display("JMPC PC 0x%0x + offset %0d",pc,$signed(offset_w));
+ 2'b11://jmpnc
+ $display("JMPNC PC 0x%0x + offset %0d",pc,$signed(offset_w));
+ endcase
+
+ //Arithmetic
+ ALU:
+ case(instruction[27:25])
+ 3'd0:$display("AND R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ 3'd1:$display("OR R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ 3'd2:$display("XOR R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ 3'd3:$display("ADD R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ 3'd4:$display("MUL R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ 3'd5:$display("SHL R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ 3'd6:$display("SHR R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ default:$display("CMP R%0d with R%0d+%d",pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ endcase
+
+ LDRF:
+ case(instruction[27:26])
+ 2'b00://ldrz
+ $display("LDRZ R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ 2'b01://ldrnz
+ $display("LDRNZ R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ 2'b10://ldrc
+ $display("LDRC R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ 2'b11://ldrnc
+ $display("LDRNC R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
+ endcase
+
+ default:
+ if(!reset)
+ begin
+ $display("Unknown Command %x",instruction[31:28]);
+ $stop;
+ end
+ endcase
+ end
+ else
+ $display("[ID stage] STALLED!",instruction[31:28]);
+ end
+//synthesys translate_on
+ end
+
+endmodule
Index: qrisc32/trunk/Readme.txt
===================================================================
--- qrisc32/trunk/Readme.txt (nonexistent)
+++ qrisc32/trunk/Readme.txt (revision 2)
@@ -0,0 +1,6 @@
+ Project Qrisc32 is risc cpu implementation, purpose is studying
+ "Digital System Design" course at Kyoung Hee University during my PhD earning.
+ Testbench runs 3 different sorting algorithms on qrisc32 and shows cycles for
+ each turn. For observing instruction set , please refer to "risc_report.pdf" file.
+ For running simulation you should use qrisc32_TB.do in Modelsim.
+ Copyright (C) 2010 Vinogradov Viacheslav.
Index: qrisc32/trunk/qrisc32_IF.sv
===================================================================
--- qrisc32/trunk/qrisc32_IF.sv (nonexistent)
+++ qrisc32/trunk/qrisc32_IF.sv (revision 2)
@@ -0,0 +1,91 @@
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Project Qrisc32 is risc cpu implementation, purpose is studying
+// Digital System Design course at Kyoung Hee University during my PhD earning
+// Copyright (C) 2010 Vinogradov Viacheslav
+//
+// This library 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 library 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 library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+//
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+
+import risc_pack::*;
+
+module qrisc32_IF(
+ input clk,reset,
+ interface avm_instructions,//avalon master port only for reading instructions
+
+ input pipe_stall,//feed back from MEM stage
+
+ input new_address_valid,//feed back from EX stage
+ input[31:0] new_address,//feed back from EX stage
+
+ output bit[31:0] instruction,
+ output bit[31:0] pc
+ );
+
+import risc_pack::*;
+
+ bit[2:0] offset_w;//
+ bit[31:0] base_w;//
+ wire[31:0] jump_address_w = base_w+offset_w;
+
+ wire if_stall = avm_instructions.wait_req | pipe_stall;
+
+ bit[31:0] stalled_adr0;
+ bit[31:0] stalled_adr1;
+
+ always_comb
+ begin
+ pc<=avm_instructions.address_r;//
+
+ base_w=avm_instructions.address_r;
+ offset_w=4;
+ if(if_stall)
+ offset_w=0;
+ else
+ if(new_address_valid)
+ begin
+ base_w=new_address;
+ offset_w=0;
+ end
+ end
+
+ always@(posedge clk)// or posedge reset)
+ if(reset)
+ begin
+ avm_instructions.address_r<='0;//reset address!
+ avm_instructions.rd<=1;//forever =1
+ instruction<='0;//=ldr R0,R0 =nop
+ end
+ else
+ begin
+ if(~if_stall)
+ begin
+ instruction<=avm_instructions.data_r;
+ avm_instructions.address_r<=jump_address_w;
+ stalled_adr0<=jump_address_w;
+ stalled_adr1<=stalled_adr0;
+ end
+ else
+ begin
+ avm_instructions.address_r<=stalled_adr0;
+ //instruction<='0;
+ //instruction<=avm_instructions.data_r;
+ $display("[IF stage] Stalled->%s",(pipe_stall)?"Mem stage is stalled":"Fetching is stalled");
+ end
+ end
+
+endmodule
Index: qrisc32/trunk/qrisc32_MEM.sv
===================================================================
--- qrisc32/trunk/qrisc32_MEM.sv (nonexistent)
+++ qrisc32/trunk/qrisc32_MEM.sv (revision 2)
@@ -0,0 +1,142 @@
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Project Qrisc32 is risc cpu implementation, purpose is studying
+// Digital System Design course at Kyoung Hee University during my PhD earning
+// Copyright (C) 2010 Vinogradov Viacheslav
+//
+// This library 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 library 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 library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+//
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+
+import risc_pack::*;
+
+module qrisc32_MEM(
+ input clk,reset,
+ interface avm_data_read,//avalon master port only for reading data
+ interface avm_data_write,//avalon master port only for writing data
+ input pipe_struct pipe_mem_in,
+ output pipe_struct pipe_mem_out,
+ output bit pipe_stall,
+ input verbose
+ );
+
+ import risc_pack::*;
+
+ bit rd_stall;
+ bit wr_stall;
+ wire[31:0] addr_w = pipe_mem_in.val_r1;
+
+ pipe_struct pipe_mem_in0,pipe_mem_in1;
+
+ always_comb
+ pipe_stall<=rd_stall | wr_stall;
+
+ always@(posedge clk)
+ if(reset)
+ begin
+ avm_data_read.address_r<='0;
+ avm_data_read.rd<='0;
+ avm_data_read.wr<='0;
+ rd_stall<=0;
+ pipe_mem_out<='0;
+ pipe_mem_in0<='0;
+ pipe_mem_in1<='0;
+ end
+ else
+ begin
+ if(pipe_mem_in.read_mem==1)
+ avm_data_read.address_r<=addr_w;//asserted addr
+
+ avm_data_read.rd<=pipe_mem_in.read_mem;//||pipe_mem_in0.read_mem||pipe_mem_in1.read_mem;
+
+ pipe_mem_in0<=pipe_mem_in;//addr asserted
+ pipe_mem_in1<=pipe_mem_in0;//just wait cycle
+
+ if(avm_data_read.wait_req==0 && pipe_mem_in1.read_mem==1)// it has been read ok(sram access is 2 cycles)
+ begin
+ //if(~pipe_mem_in.write_reg)
+ begin
+ if(verbose)
+ $display("[MEM stage] access to dst register");
+ rd_stall<=0;
+ pipe_mem_out<=pipe_mem_in;
+ pipe_mem_out.dst_r<=pipe_mem_in1.dst_r;
+ pipe_mem_out.val_dst<=avm_data_read.data_r;//result of read
+ pipe_mem_out.write_reg<=1;
+ end
+ //else
+ //if(~pipe_mem_in.incr_r2_enable)
+ //begin
+ // if(verbose)
+ // $display("[MEM stage] access to src2 register");
+ // rd_stall<=0;
+ // pipe_mem_out<=pipe_mem_in;
+ //
+ // pipe_mem_out.src_r2<=pipe_mem_in1.dst_r;
+ // pipe_mem_out.incr_r2_enable<=1;
+ // pipe_mem_out.val_r2<=avm_data_read.data_r;//result of read
+ //end
+ //else
+ //begin
+ // if(verbose)
+ // $display("[MEM stage] access to dst register and STALL pipeline!");
+ // rd_stall<=1;
+ // pipe_mem_out<=pipe_mem_in1;
+ // pipe_mem_out.val_dst<=avm_data_read.data_r;//result of read
+ //end
+ end
+ else
+ begin
+ rd_stall<=0;
+ if(rd_stall)//if previous op was stalled
+ begin
+ pipe_mem_out<=pipe_mem_in0;
+ end
+ else
+ begin
+ pipe_mem_out<=pipe_mem_in;
+ if(pipe_mem_in.read_mem)//if read access then
+ pipe_mem_out.write_reg<='0;//clear write bit register
+ end
+ end
+ end
+
+ always@(posedge clk)
+ if(reset)
+ begin
+ avm_data_write.address_r<='0;
+ avm_data_write.data_w<='0;
+ avm_data_write.rd<='0;
+ avm_data_write.wr<='0;
+ wr_stall<='0;
+ end
+ else
+ begin
+ if(pipe_mem_in.write_mem)
+ begin
+ avm_data_write.address_r<=addr_w;
+ avm_data_write.data_w<=pipe_mem_in.val_dst;
+ avm_data_write.wr<=1;
+ wr_stall<=0;
+ end
+ else
+ begin
+ avm_data_write.wr<='0;
+ wr_stall<=0;
+ end
+ end
+
+endmodule
Index: qrisc32/trunk/qrisc32_TB.do
===================================================================
--- qrisc32/trunk/qrisc32_TB.do (nonexistent)
+++ qrisc32/trunk/qrisc32_TB.do (revision 2)
@@ -0,0 +1,69 @@
+vsim -novopt work.qrisc32_tb
+
+onerror {resume}
+quietly WaveActivateNextPane {} 0
+add wave -noupdate /qrisc32_tb/UUT/clk
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/reset
+add wave -noupdate -divider {pipe stalled}
+add wave -noupdate /qrisc32_tb/UUT/pipe_stall
+add wave -noupdate -divider {Instruction bus}
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_instructions_data
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_instructions_addr
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_instructions_rd
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_instructions_wait_req
+add wave -noupdate -divider {Data Read Bus}
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_datar_data
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_datar_addr
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_datar_rd
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_datar_wait_req
+add wave -noupdate -divider {Data Write Bus}
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_dataw_data
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_dataw_addr
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_dataw_wr
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/avm_dataw_wait_req
+add wave -noupdate -divider Registers
+add wave -noupdate -radix hexadecimal -subitemconfig {{/qrisc32_tb/UUT/qrisc32_ID/rf[31]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[30]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[29]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[28]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[27]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[26]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[25]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[24]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[23]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[22]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[21]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[20]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[19]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[18]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[17]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[16]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[15]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[14]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[13]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[12]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[11]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[10]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[9]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[8]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[7]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[6]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[5]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[4]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[3]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[2]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[1]} {-height 15 -radix hexadecimal} {/qrisc32_tb/UUT/qrisc32_ID/rf[0]} {-height 15 -radix hexadecimal}} /qrisc32_tb/UUT/qrisc32_ID/rf
+add wave -noupdate -divider pipe
+add wave -noupdate -radix decimal /qrisc32_tb/UUT/qrisc32_ID/offset_w
+add wave -noupdate -radix hexadecimal -subitemconfig {/qrisc32_tb/UUT/pipe_id_out.val_r1 {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.val_r2 {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.val_dst {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.src_r2 {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.src_r1 {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.dst_r {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.incr_r2 {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.incr_r2_enable {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.write_reg {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.read_mem {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.write_mem {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.and_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.or_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.xor_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.add_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.mul_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.cmp_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.shl_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.shr_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.jmpunc {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.jmpz {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.jmpnz {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.jmpc {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_id_out.jmpnc {-height 15 -radix hexadecimal}} /qrisc32_tb/UUT/pipe_id_out
+add wave -noupdate -radix hexadecimal -subitemconfig {/qrisc32_tb/UUT/pipe_ex_out.val_r1 {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.val_r2 {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.val_dst {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.src_r2 {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.src_r1 {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.dst_r {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.incr_r2 {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.incr_r2_enable {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.write_reg {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.read_mem {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.write_mem {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.and_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.or_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.xor_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.add_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.mul_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.cmp_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.shl_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.shr_op {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.jmpunc {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.jmpz {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.jmpnz {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.jmpc {-height 15 -radix hexadecimal} /qrisc32_tb/UUT/pipe_ex_out.jmpnc {-height 15 -radix hexadecimal}} /qrisc32_tb/UUT/pipe_ex_out
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/pipe_mem_out
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/instruction
+add wave -noupdate -divider Flags
+add wave -noupdate /qrisc32_tb/UUT/qrisc32_EX/flagZ
+add wave -noupdate /qrisc32_tb/UUT/qrisc32_EX/flagC
+add wave -noupdate /qrisc32_tb/UUT/qrisc32_EX/new_address_valid
+add wave -noupdate -radix hexadecimal /qrisc32_tb/UUT/qrisc32_EX/new_address
+add wave -noupdate -radix unsigned {/qrisc32_tb/Dram/sram[9]}
+add wave -noupdate -radix unsigned {/qrisc32_tb/Dram/sram[8]}
+add wave -noupdate -radix unsigned {/qrisc32_tb/Dram/sram[7]}
+add wave -noupdate -radix unsigned {/qrisc32_tb/Dram/sram[6]}
+add wave -noupdate -radix unsigned {/qrisc32_tb/Dram/sram[5]}
+add wave -noupdate -radix unsigned {/qrisc32_tb/Dram/sram[4]}
+add wave -noupdate -radix unsigned {/qrisc32_tb/Dram/sram[3]}
+add wave -noupdate -radix unsigned {/qrisc32_tb/Dram/sram[2]}
+add wave -noupdate -radix unsigned {/qrisc32_tb/Dram/sram[1]}
+add wave -noupdate -radix unsigned {/qrisc32_tb/Dram/sram[0]}
+add wave -noupdate -radix unsigned /qrisc32_tb/cycles
+add wave -noupdate -radix unsigned /qrisc32_tb/UUT/qrisc32_ID/nop_counter
+add wave -noupdate -radix unsigned /qrisc32_tb/UUT/qrisc32_ID/jmp_counter
+add wave -noupdate -radix unsigned /qrisc32_tb/UUT/qrisc32_ID/alu_counter
+add wave -noupdate -radix unsigned /qrisc32_tb/UUT/qrisc32_ID/oth_counter
+TreeUpdate [SetDefaultTree]
+WaveRestoreCursors {{Cursor 2} {10130 ns} 0}
+configure wave -namecolwidth 278
+configure wave -valuecolwidth 73
+configure wave -justifyvalue left
+configure wave -signalnamewidth 0
+configure wave -snapdistance 10
+configure wave -datasetprefix 0
+configure wave -rowmargin 4
+configure wave -childrowmargin 2
+configure wave -gridoffset 0
+configure wave -gridperiod 1
+configure wave -griddelta 40
+configure wave -timeline 0
+configure wave -timelineunits ns
+update
+WaveRestoreZoom {0 ns} {17924 ns}
+
Index: qrisc32/trunk/qrisc32.sv
===================================================================
--- qrisc32/trunk/qrisc32.sv (nonexistent)
+++ qrisc32/trunk/qrisc32.sv (revision 2)
@@ -0,0 +1,144 @@
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Project Qrisc32 is risc cpu implementation, purpose is studying
+// Digital System Design course at Kyoung Hee University during my PhD earning
+// Copyright (C) 2010 Vinogradov Viacheslav
+//
+// This library 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 library 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 library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+//
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+//-------------------------------------------------------------------------------------------
+// Title : qrisc32
+// Design : qrisc32
+// Author : vinogradov@opencores.org
+//5 stages risc cpu
+//with 3 avalon interfaces:
+// - Data Read Avalon interface
+// - Data Write Avalon interface
+// - Instruction Read Avalon interface
+//--------------------------------------------------------------------------------------------
+
+`timescale 1 ns / 1 ns
+
+module qrisc32(
+ input clk,reset,
+
+ //avalon master port only for reading instructions
+ input[31:0] avm_instructions_data,
+ output[31:0] avm_instructions_addr,
+ output avm_instructions_rd,
+ input avm_instructions_wait_req,
+
+ //avalon master port only for reading data avm_data_read
+ input[31:0] avm_datar_data,
+ output[31:0] avm_datar_addr,
+ output avm_datar_rd,
+ input avm_datar_wait_req,
+
+ //avalon master port only for writing data
+ output[31:0] avm_dataw_data,
+ output[31:0] avm_dataw_addr,
+ output avm_dataw_wr,
+ input avm_dataw_wait_req,
+
+ input verbose//for simlation
+
+ );
+
+import risc_pack::*;
+
+ avalon_port avm_instructions(),avm_data_read(),avm_data_write();
+
+ //Instruction read port
+ assign avm_instructions.data_r = avm_instructions_data;
+ assign avm_instructions_addr = avm_instructions.address_r;
+ assign avm_instructions_rd = avm_instructions.rd;
+ assign avm_instructions.wait_req = avm_instructions_wait_req;
+
+ //Data read port
+ assign avm_data_read.data_r = avm_datar_data;
+ assign avm_datar_addr = avm_data_read.address_r;
+ assign avm_datar_rd = avm_data_read.rd;
+ assign avm_data_read.wait_req = avm_datar_wait_req;
+
+ //Data write port
+ assign avm_dataw_data = avm_data_write.data_w;
+ assign avm_dataw_addr = avm_data_write.address_r;
+ assign avm_dataw_wr = avm_data_write.wr;
+ assign avm_data_write.wait_req = avm_dataw_wait_req;
+
+
+ pipe_struct // I decode - Ex - MEM access
+ pipe_id_out,pipe_ex_out,pipe_mem_out;
+
+ wire[31:0] instruction,pc;
+ wire new_address_valid_ex;
+ wire[31:0] new_address_ex;
+
+ wire new_address_valid_mem;
+ wire[31:0] new_address_mem;
+
+
+ wire pipe_stall;
+
+ qrisc32_IF qrisc32_IF(
+ .clk(clk),
+ .reset(reset),
+ .pipe_stall(pipe_stall),
+ .avm_instructions(avm_instructions),
+ .new_address_valid(new_address_valid_ex),
+ .new_address(new_address_ex),
+
+ .instruction(instruction),
+ .pc(pc)
+ );
+
+ qrisc32_ID qrisc32_ID(
+ .clk(clk),
+ .reset(reset),
+ .pipe_stall(pipe_stall),
+ .instruction(instruction),
+ .pc(pc),
+ .pipe_wb_mem(pipe_mem_out),//for memory read
+ .pipe_wb_ex(pipe_ex_out),//for R2 register and ALU operations only
+ .pipe_id_out(pipe_id_out),
+ .verbose(verbose)
+ );
+
+ qrisc32_EX qrisc32_EX(
+ .clk(clk),
+ .reset(reset),
+ .pipe_stall(pipe_stall),
+ .pipe_ex_in(pipe_id_out),
+ .pipe_ex_out(pipe_ex_out),
+ .new_address_valid(new_address_valid_ex),
+ .new_address(new_address_ex)
+ );
+
+ qrisc32_MEM qrisc32_MEM(
+ .clk(clk),
+ .reset(reset),
+ .pipe_mem_in(pipe_ex_out),
+ .avm_data_read(avm_data_read),
+ .avm_data_write(avm_data_write),
+ .pipe_mem_out(pipe_mem_out),
+ .pipe_stall(pipe_stall),
+ .verbose(verbose)
+ );
+
+
+
+endmodule