├── README.md
├── comparator.v
├── mips.v
├── grf.v
├── alu.v
├── dm_readunit.sv
├── constants.v
├── forwardController.v
├── im.sv
├── dm.sv
├── multiplier.v
├── cp0.v
├── controller.sv
├── cpu.v
└── LICENSE
/README.md:
--------------------------------------------------------------------------------
1 | # MIPSCPU
2 | 一个简易的 MIPS CPU。北航 2018 级计算机组成原理课程设计。
3 |
4 | ## 使用方法
5 | 使用 Mars 编译 CPU 代码,将 0x3000 起始的 text 区以 16 进制格式导入 code.txt,然后仿真即可。
6 |
7 | ## 支持的指令集
8 | MIPS-C3: LB, LBU, LH, LHU, LW, SB, SH, SW, ADD, ADDU, SUB, SUBU, MULT, MULTU, DIV, DIVU, SLL, SRL, SRA, SLLV, SRLV, SRAV, AND, OR, XOR, NOR, ADDI, ADDIU, ANDI, ORI, XORI, LUI, SLT, SLTI, SLTIU, SLTU, BEQ, BNE, BLEZ, BGTZ, BLTZ, BGEZ, J, JAL, JALR, JR, MFHI, MFLO, MTHI, MTLO
9 |
10 | CP0 相关:MFC0, MTC0, ERET
11 |
12 | ## 外设
13 | 两个定时器,支持中断功能。寄存器地址分别在 0x7F00 - 0x7F0B, 0x7F10 - 0x7F1B。
14 |
--------------------------------------------------------------------------------
/comparator.v:
--------------------------------------------------------------------------------
1 | `include "constants.v"
2 | module Comparator (
3 | input signed [31:0] A,
4 | input signed [31:0] B,
5 | input [3:0] ctrl,
6 | output reg action
7 | );
8 |
9 | always @(*) begin
10 | action = 0;
11 | case (ctrl)
12 | `cmpEqual:
13 | action = (A == B) ? 1 : 0;
14 | `cmpNotEqual:
15 | action = (A != B) ? 1 : 0;
16 | `cmpLessThanOrEqualToZero:
17 | action = (A <= 0) ? 1 : 0;
18 | `cmpLessThanZero:
19 | action = (A < 0) ? 1 : 0;
20 | `cmpGreaterThanOrEqualToZero:
21 | action = (A >= 0) ? 1 : 0;
22 | `cmpGreaterThanZero:
23 | action = (A > 0) ? 1 : 0;
24 | endcase
25 | end
26 |
27 | endmodule
--------------------------------------------------------------------------------
/mips.v:
--------------------------------------------------------------------------------
1 | module mycpu_top(
2 | input clk,
3 | input resetn,
4 | input [5:0] int,
5 |
6 | output inst_sram_en,
7 | output [3:0] inst_sram_wen,
8 | output [31:0] inst_sram_addr,
9 | output [31:0] inst_sram_wdata,
10 | input [31:0] inst_sram_rdata,
11 |
12 | output data_sram_en,
13 | output [3:0] data_sram_wen,
14 | output [31:0] data_sram_addr,
15 | output [31:0] data_sram_wdata,
16 | input [31:0] data_sram_rdata,
17 |
18 | output [31:0] debug_wb_pc,
19 | output [3:0] debug_wb_rf_wen,
20 | output [4:0] debug_wb_rf_wnum,
21 | output [31:0] debug_wb_rf_wdata
22 | );
23 |
24 | assign inst_sram_en = 1;
25 | assign inst_sram_wen = 0;
26 | assign inst_sram_wdata = 32'b0;
27 |
28 | CPU cpu(
29 | .clk(clk),
30 | .reset(~resetn),
31 | .irq(int),
32 |
33 | .inst_sram_addr(inst_sram_addr),
34 | .inst_sram_rdata(inst_sram_rdata),
35 |
36 | .data_sram_en(data_sram_en),
37 | .data_sram_wen(data_sram_wen),
38 | .data_sram_addr(data_sram_addr),
39 | .data_sram_wdata(data_sram_wdata),
40 | .data_sram_rdata(data_sram_rdata),
41 |
42 | .debug_wb_pc(debug_wb_pc),
43 | .debug_wb_rf_wen(debug_wb_rf_wen),
44 | .debug_wb_rf_wnum(debug_wb_rf_wnum),
45 | .debug_wb_rf_wdata(debug_wb_rf_wdata)
46 | );
47 |
48 | endmodule
--------------------------------------------------------------------------------
/grf.v:
--------------------------------------------------------------------------------
1 | `include "constants.v"
2 | module GeneralRegisterFile(
3 | input [4:0] readAddress1,
4 | output reg [31:0] readOutput1,
5 | input [4:0] readAddress2,
6 | output reg [31:0] readOutput2,
7 | input [4:0] writeAddress,
8 | input [31:0] writeData,
9 | input clk,
10 | input reset,
11 | input [31:0] debugPC,
12 | output [31:0] debug_wb_pc,
13 | output [3:0] debug_wb_rf_wen,
14 | output [4:0] debug_wb_rf_wnum,
15 | output [31:0] debug_wb_rf_wdata
16 | );
17 |
18 | assign debug_wb_pc = debugPC;
19 | assign debug_wb_rf_wen = writeAddress != 0;
20 | assign debug_wb_rf_wnum = writeAddress;
21 | assign debug_wb_rf_wdata = writeData;
22 |
23 | reg [31:0] registers [31:0];
24 |
25 | always @(*) begin
26 | readOutput1 = registers[readAddress1];
27 | readOutput2 = registers[readAddress2];
28 | end
29 |
30 | integer i;
31 | always @(posedge clk) begin
32 | if (reset) begin
33 | for (i = 0; i <= 31; i = i + 1) begin
34 | registers[i] <= 0;
35 | end
36 | end
37 | else begin
38 | if (writeAddress != 0) begin
39 | `ifdef DEBUG
40 | $display("@%h: $%d <= %h", debugPC, writeAddress, writeData);
41 | `else
42 | $display("%d@%h: $%d <= %h", $time, debugPC, writeAddress, writeData);
43 | `endif
44 | registers[writeAddress] <= writeData;
45 | end
46 | end
47 | end
48 |
49 | endmodule
50 |
--------------------------------------------------------------------------------
/alu.v:
--------------------------------------------------------------------------------
1 | `include "constants.v"
2 | module ArithmeticLogicUnit (
3 | input [31:0] A,
4 | input [31:0] B,
5 | input [3:0] ctrl,
6 | output reg [31:0] out,
7 | output overflow // TODO: overflow bit is untested.
8 | );
9 |
10 | wire [32:0] extA = {A[31], A}, extB = {B[31], B};
11 | reg [32:0] tmp;
12 | assign overflow = tmp[32] != tmp[31];
13 |
14 | always @(*) begin
15 | tmp = 0;
16 | out = 0;
17 | case (ctrl)
18 | `ifdef DEBUG
19 |
20 | `aluDisabled:
21 | out = 'bx;
22 | `endif
23 |
24 | `aluAdd: begin
25 | tmp = extA + extB;
26 | out = tmp[31:0];
27 | end
28 | `aluSub: begin
29 | tmp = extA - extB;
30 | out = tmp[31:0];
31 | end
32 |
33 | `aluOr:
34 | out = A | B;
35 | `aluAnd:
36 | out = A & B;
37 | `aluXor:
38 | out = A ^ B;
39 | `aluNor:
40 | out = ~(A | B);
41 |
42 | `aluShiftLeft:
43 | out = A << B[4:0];
44 | `aluShiftRight:
45 | out = A >> B[4:0];
46 | `aluArithmeticShiftRight:
47 | out = $signed(A) >>> B[4:0];
48 |
49 | `aluSLT: begin
50 | out = ($signed(A) < $signed(B)) ? 32'b1 : 32'b0;
51 | end
52 |
53 | `aluSLTU: begin
54 | out = (A < B) ? 32'b1 : 32'b0;
55 | end
56 | endcase
57 | end
58 |
59 | endmodule
60 |
--------------------------------------------------------------------------------
/dm_readunit.sv:
--------------------------------------------------------------------------------
1 | `include "constants.v"
2 |
3 | module DataMemoryReader(
4 | input readEnable,
5 | input extendCtrl,
6 | output logic [31:0] readData,
7 | input [1:0] widthCtrl,
8 | input [31:0] address,
9 | input [31:0] data_sram_rdata
10 | );
11 |
12 | logic [15:0] halfWord;
13 | logic [7:0] readbyte;
14 | always_comb begin
15 | readData = 0;
16 | if (!readEnable) begin
17 | readData = 'bX;
18 | end
19 | else if (widthCtrl == `memWidth4) begin
20 | readData = data_sram_rdata;
21 | end
22 | else if (widthCtrl == `memWidth2) begin
23 | if (address[1]) begin
24 | halfWord = data_sram_rdata[31:16];
25 | end
26 | else begin
27 | halfWord = data_sram_rdata[15:0];
28 | end
29 | if (extendCtrl) begin
30 | readData = $signed(halfWord);
31 | end
32 | else begin
33 | readData = halfWord;
34 | end
35 | end
36 | else if (widthCtrl == `memWidth1) begin
37 | if (address[1:0] == 3) begin
38 | readbyte = data_sram_rdata[31:24];
39 | end
40 | else if (address[1:0] == 2) begin
41 | readbyte = data_sram_rdata[23:16];
42 | end
43 | else if (address[1:0] == 1) begin
44 | readbyte = data_sram_rdata[15:8];
45 | end
46 | else if (address[1:0] == 0) begin
47 | readbyte = data_sram_rdata[7:0];
48 | end
49 | if (extendCtrl) begin
50 | readData = $signed(readbyte);
51 | end
52 | else begin
53 | readData = readbyte;
54 | end
55 | end
56 | end
57 |
58 |
59 | endmodule
--------------------------------------------------------------------------------
/constants.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 |
3 | `define aluDisabled 0
4 | `define aluSub 1
5 | `define aluOr 2
6 | `define aluAnd 3
7 | `define aluShiftLeft 4
8 | `define aluAdd 5
9 | `define aluNor 6
10 | `define aluXor 7
11 | `define aluShiftRight 8
12 | `define aluArithmeticShiftRight 9
13 | `define aluSLT 10
14 | `define aluSLTU 11
15 |
16 | `define cmpEqual 1
17 | `define cmpNotEqual 2
18 | `define cmpLessThanOrEqualToZero 3
19 | `define cmpLessThanZero 4
20 | `define cmpGreaterThanOrEqualToZero 5
21 | `define cmpGreaterThanZero 6
22 |
23 | `define memWidth4 1
24 | `define memWidth2 2
25 | `define memWidth1 3
26 |
27 | // `define DEBUG
28 | // `define VERBOSE
29 |
30 | `define grfWriteDisable 0
31 | `define grfWriteALU 1
32 | `define grfWriteMem 2
33 | `define grfWritePC 3
34 | `define grfWriteMul 4
35 | `define grfWriteCP0 5
36 |
37 | `define absJumpImmediate 1
38 | `define absJumpRegister 0
39 |
40 | `define stallNone 0
41 | `define stallFetch 1
42 | `define stallDecode 2
43 | `define stallExecution 3
44 | `define stallMemory 4
45 | `define stallWriteBack 5
46 |
47 | `define stageD 3'd1
48 | `define stageE 3'd2
49 | `define stageM 3'd3
50 | `define stageW 3'd4
51 |
52 | `define mtDisabled 0
53 | `define mtMultiply 1
54 | `define mtMultiplyUnsigned 2
55 | `define mtDivide 3
56 | `define mtDivideUnsigned 4
57 | `define mtSetHI 5
58 | `define mtSetLO 6
59 | `define mtMSUB 7
60 | `define mtMADD 8
61 | `define mtMADDU 9
62 |
63 | `define ctrlNoException 0
64 | `define ctrlUnknownInstruction 1
65 | `define ctrlERET 2
66 | `define ctrlSyscall 3
67 | `define ctrlBreak 4
68 |
69 | `define causeInt 0
70 | `define causeERET 16
71 | `define causeAdEL 4
72 | `define causeAdES 5
73 | `define causeRI 10
74 | `define causeOv 12
75 | `define causeSyscall 8
76 | `define causeBreak 9
--------------------------------------------------------------------------------
/forwardController.v:
--------------------------------------------------------------------------------
1 | `include "constants.v"
2 | module ForwardController (
3 | input [4:0] request,
4 | input [31:0] original,
5 | input enabled,
6 | input [31:0] debugPC,
7 | input [7:0] debugStage,
8 | output reg [31:0] value,
9 | output stallExec,
10 |
11 | // priority: src1 > src2
12 | input src1Valid,
13 | input [4:0] src1Reg,
14 | input [31:0] src1Value,
15 |
16 | input src2Valid,
17 | input [4:0] src2Reg,
18 | input [31:0] src2Value,
19 |
20 | input src3Valid,
21 | input [4:0] src3Reg,
22 | input [31:0] src3Value
23 | );
24 |
25 | reg stall;
26 | assign stallExec = stall & enabled;
27 |
28 | always @(*) begin
29 | if (request == 0) begin
30 | value = 0;
31 | stall = 0;
32 | end
33 | else if (src1Reg == request) begin
34 | if (!src1Valid) begin
35 | stall = 1;
36 | value = 'bx;
37 | end
38 | else begin
39 | stall = 0;
40 | value = src1Value;
41 | end
42 | end
43 | else if (src2Reg == request) begin
44 | if (!src2Valid) begin
45 | stall = 1;
46 | value = 'bx;
47 | end
48 | else begin
49 | stall = 0;
50 | value = src2Value;
51 | end
52 | end
53 | else if (src3Reg == request) begin
54 | if (!src3Valid) begin
55 | stall = 1;
56 | value = 'bx;
57 | end
58 | else begin
59 | stall = 0;
60 | value = src3Value;
61 | end
62 | end
63 | else begin
64 | value = original;
65 | stall = 0;
66 | end
67 | end
68 |
69 | endmodule
70 |
--------------------------------------------------------------------------------
/im.sv:
--------------------------------------------------------------------------------
1 | `include "constants.v"
2 | module InstructionMemory(
3 | input clk,
4 | input reset,
5 | input absJump,
6 | input pcStall,
7 | input hang,
8 | input [31:0] absJumpAddress, // In bytes
9 | output [31:0] outputPC,
10 | output [31:0] instruction,
11 | output reg exception,
12 | output [31:0] inst_sram_addr,
13 | input [31:0] inst_sram_rdata,
14 | output bubble
15 | );
16 |
17 |
18 | // reg [31:0] memory [4095:0];
19 | wire isHanging;
20 |
21 |
22 | // wire [31:0] realAddress = pc - 32'h3000;
23 | reg [31:0] pc;
24 | reg hangState;
25 | assign outputPC = hangState ? 0 : pc;
26 | assign bubble = hangState;
27 | // assign instruction = isHanging ? 0 : memory[realAddress[13:2]];
28 | assign instruction = isHanging ? 0 : inst_sram_rdata;
29 | assign isHanging = hang || hangState;
30 |
31 | always @(*) begin
32 | exception = 0;
33 | if (!hangState) begin
34 | if (pc[1:0] != 0) begin
35 | exception = 1;
36 | end
37 | end
38 | end
39 |
40 | logic [31:0] nextPC;
41 | assign inst_sram_addr = nextPC;
42 |
43 | always_comb begin
44 | if (reset) begin
45 | nextPC = 32'hBFC00000;
46 | end else begin
47 | if (pcStall) begin
48 | nextPC = pc;
49 | end
50 | else if (absJump) begin
51 | nextPC = absJumpAddress;
52 | end
53 | else begin
54 | if (hang) begin
55 | nextPC = pc;
56 | end
57 | if (!isHanging) begin
58 | nextPC = pc + 4;
59 | end
60 | end
61 | end
62 | end
63 |
64 | always @(posedge clk) begin
65 | `ifdef DEBUG
66 | // $display("@%h, delta = %d, instruction = %h", pc, relJumpDelta, instruction);
67 | `endif
68 | if (reset)
69 | begin
70 | hangState <= 0;
71 | end
72 | else begin
73 | if (pcStall) begin
74 | end
75 | else if (absJump) begin
76 | hangState <= 0;
77 | end
78 | else begin
79 | if (hang) begin
80 | hangState <= 1;
81 | end
82 | end
83 | end
84 | pc <= nextPC;
85 | end
86 |
87 | always @(*) begin
88 | `ifdef VERBOSE
89 | $display("PC @ %h", pc);
90 | `endif
91 | end
92 |
93 | endmodule
94 |
--------------------------------------------------------------------------------
/dm.sv:
--------------------------------------------------------------------------------
1 | `include "constants.v"
2 | module DataMemory(
3 | input clk,
4 | input reset,
5 | input writeEnable,
6 | input readEnable,
7 | input [1:0] widthCtrl,
8 | input [31:0] address,
9 | input [31:0] writeDataIn,
10 | input [31:0] debugPC,
11 | output exception,
12 |
13 | output data_sram_en,
14 | output logic [3:0] data_sram_wen,
15 | output [31:0] data_sram_addr,
16 | output [31:0] data_sram_wdata
17 | );
18 |
19 | assign data_sram_addr = address & 32'h1FFFFFFF;
20 | assign data_sram_en = readEnable || writeEnable;
21 |
22 | logic addressException;
23 | assign exception = addressException;
24 | always_comb begin
25 | addressException = 0;
26 | if (widthCtrl == `memWidth4) begin
27 | if (address[1:0] != 0) begin
28 | addressException = 1;
29 | end
30 | end
31 | else if (widthCtrl == `memWidth2) begin
32 | if (address[0] != 0) begin
33 | addressException = 1;
34 | end
35 | end
36 | end
37 |
38 | logic [31:0] writeData;
39 | assign data_sram_wdata = writeData;
40 |
41 | always_comb begin
42 | writeData = 0;
43 | data_sram_wen = 4'b0000;
44 | if (!addressException && writeEnable) begin
45 | if (widthCtrl == `memWidth4) begin
46 | writeData = writeDataIn;
47 | data_sram_wen = 4'b1111;
48 | end
49 | else if (widthCtrl == `memWidth2) begin
50 | if (address[1] == 1) begin
51 | writeData = {writeDataIn[15:0], 16'b0};
52 | data_sram_wen = 4'b1100;
53 | end
54 | else begin
55 | writeData = {16'b0, writeDataIn[15:0]};
56 | data_sram_wen = 4'b0011;
57 | end
58 | end
59 | else if (widthCtrl == `memWidth1) begin
60 | if (address[1:0] == 3) begin
61 | writeData = {writeDataIn[7:0], 24'b0};
62 | data_sram_wen = 4'b1000;
63 | end
64 | else if (address[1:0] == 2) begin
65 | writeData = {8'b0, writeDataIn[7:0], 16'b0};
66 | data_sram_wen = 4'b0100;
67 | end
68 | else if (address[1:0] == 1) begin
69 | writeData = {16'b0, writeDataIn[7:0], 8'b0};
70 | data_sram_wen = 4'b0010;
71 | end
72 | else begin
73 | writeData = {24'b0, writeDataIn[7:0]};
74 | data_sram_wen = 4'b0001;
75 | end
76 | end
77 | end
78 | end
79 |
80 | endmodule
81 |
--------------------------------------------------------------------------------
/multiplier.v:
--------------------------------------------------------------------------------
1 | `include "constants.v"
2 |
3 | module Multiplier (
4 | input reset,
5 | input clk,
6 | input start,
7 | input [31:0] A,
8 | input [31:0] B,
9 | input [3:0] ctrl,
10 | output reg busy,
11 | output reg [31:0] HI,
12 | output reg [31:0] LO
13 | );
14 |
15 | localparam MultiplicationDelay = 7;
16 | reg [31:0] inA, inB;
17 | reg [3:0] op;
18 |
19 | wire [63:0] multiplyResult;
20 | wire [63:0] unsignedMultiplyResult;
21 | mult_signed_0 signedMul(.A(inA), .B(inB), .CLK(clk), .SCLR(start), .P(multiplyResult));
22 | mult_unsigned_0 unsignedMul(.A(inA), .B(inB), .CLK(clk), .SCLR(start), .P(unsignedMultiplyResult));
23 |
24 | wire [63:0] signedDivResult;
25 | wire [63:0] unsignedDivResult;
26 | wire signedDivValid, unsignedDivValid;
27 | wire inputDataValid = busy;
28 | div_signed_0 signedDiv(
29 | .aclk(clk),
30 | .aresetn(!start),
31 | .s_axis_divisor_tvalid(inputDataValid),
32 | .s_axis_divisor_tdata(inB),
33 | .s_axis_dividend_tvalid(inputDataValid),
34 | .s_axis_dividend_tdata(inA),
35 | .m_axis_dout_tdata(signedDivResult),
36 | .m_axis_dout_tvalid(signedDivValid)
37 | );
38 | div_unsigned_0 unsignedDiv(
39 | .aclk(clk),
40 | .aresetn(!start),
41 | .s_axis_divisor_tvalid(inputDataValid),
42 | .s_axis_divisor_tdata(inB),
43 | .s_axis_dividend_tvalid(inputDataValid),
44 | .s_axis_dividend_tdata(inA),
45 | .m_axis_dout_tdata(unsignedDivResult),
46 | .m_axis_dout_tvalid(unsignedDivValid)
47 | );
48 |
49 | reg [3:0] counter;
50 | reg ready;
51 | always @(*) begin
52 | ready = 0;
53 | case (op)
54 | `mtMultiply, `mtMultiplyUnsigned,`mtMSUB, `mtMADD, `mtMADDU:
55 | ready = counter > MultiplicationDelay;
56 | `mtDivide:
57 | ready = signedDivValid;
58 | `mtDivideUnsigned:
59 | ready = unsignedDivValid;
60 | endcase
61 | end
62 |
63 | always @(posedge clk) begin
64 | if (reset) begin
65 | HI <= 0;
66 | LO <= 0;
67 | busy <= 0;
68 | counter <= 'bX;
69 | end
70 | else if (start) begin
71 | if (ctrl == `mtSetHI) begin
72 | HI <= A;
73 | end
74 | else if (ctrl == `mtSetLO) begin
75 | LO <= A;
76 | end
77 | else begin
78 | inA <= A;
79 | inB <= B;
80 | op <= ctrl;
81 | counter <= 0;
82 | busy <= 1;
83 | end
84 | end
85 | else if (busy) begin
86 | if (ready) begin
87 | counter <= 'bX;
88 | busy <= 0;
89 | case (op)
90 | `mtMultiply:
91 | {HI, LO} <= multiplyResult;
92 | `mtMSUB:
93 | {HI, LO} <= {HI, LO} - multiplyResult;
94 | `mtMADD:
95 | {HI, LO} <= {HI, LO} + multiplyResult;
96 | `mtMADDU:
97 | {HI, LO} <= {HI, LO} + unsignedMultiplyResult;
98 | `mtMultiplyUnsigned:
99 | {HI, LO} <= unsignedMultiplyResult;
100 | `mtDivide: begin
101 | if (inB != 0) begin
102 | {LO, HI} <= signedDivResult;
103 | end
104 | end
105 | `mtDivideUnsigned: begin
106 | if (inB != 0) begin
107 | {LO, HI} <= unsignedDivResult;
108 | end
109 | end
110 | endcase
111 | end else begin
112 | counter <= counter + 1;
113 | end
114 | end
115 | end
116 |
117 | endmodule
--------------------------------------------------------------------------------
/cp0.v:
--------------------------------------------------------------------------------
1 | `include "constants.v"
2 |
3 | module CP0(
4 | input clk,
5 | input reset,
6 | input writeEnable,
7 | input [4:0] number,
8 | input [31:0] writeData,
9 | output [31:0] readData,
10 |
11 | input hasExceptionInPipeline,
12 |
13 | input isBD,
14 | input isException,
15 | input [4:0] exceptionCause,
16 | input [31:0] exceptionPC,
17 | input [31:0] exceptionBadVAddr,
18 |
19 | output reg jump,
20 | output reg [31:0] jumpAddress,
21 |
22 | output interruptNow,
23 | input [15:10] externalInterrupt
24 | );
25 |
26 | wire [31:0] exceptionHandler = 32'hBFC00380;
27 |
28 | reg [31:0] registers [15:0];
29 |
30 | `define CauseNumber 13
31 | `define CompareNumber 11
32 | `define CountNumber 9
33 |
34 | assign readData = registers[number];
35 |
36 | `define EPC registers[14]
37 | `define PrId registers[15]
38 | `define SR registers[12]
39 | `define EXL `SR[1]
40 | `define IE `SR[0]
41 | `define IM `SR[15:8]
42 | `define Cause registers[13]
43 | `define BD `Cause[31]
44 | `define IP `Cause[15:8]
45 | `define ExcCode `Cause[6:2]
46 | `define BadVAddr registers[8]
47 | `define Count registers[`CountNumber]
48 | `define Compare registers[`CompareNumber]
49 |
50 | assign BDReg = `BD;
51 | wire EXLReg = `EXL;
52 | wire [4:0] ExcCodeReg = `ExcCode;
53 | wire [31:0] EPCReg = `EPC;
54 |
55 | always @(*) begin
56 | jump = 0;
57 | jumpAddress = 'bx;
58 | if (isException) begin
59 | jump = 1;
60 | if (exceptionCause == `causeERET) begin
61 | jumpAddress = `EPC;
62 | end
63 | else if (exceptionCause != `causeERET) begin
64 | jumpAddress = exceptionHandler;
65 | end
66 | end
67 | end
68 | integer i;
69 | initial begin
70 | for (i = 0; i < 16; i = i + 1) begin
71 | registers[i] = 32'b0;
72 | end
73 | end
74 |
75 | reg timerInterrupt, clearTimerInterrupt;
76 | wire [15:8] interruptSource = {timerInterrupt, externalInterrupt[14:10], `Cause[9:8]};
77 | wire interruptEnabled = `IE && !`EXL && !hasExceptionInPipeline;
78 | wire [15:8] unmaskedInterrupt = interruptEnabled ? (interruptSource & `IM) : 0;
79 | wire hasInterrupt = | unmaskedInterrupt;
80 |
81 | reg pendingInterrupt;
82 | assign interruptNow = hasInterrupt;
83 |
84 |
85 | always @(posedge clk) begin
86 | if (reset) begin
87 | timerInterrupt <= 0;
88 | end
89 | else begin
90 | if (clearTimerInterrupt) begin
91 | timerInterrupt <= 0;
92 | end
93 | else begin
94 | if (`Count == `Compare && `Compare != 32'b0) begin
95 | timerInterrupt <= 1;
96 | end
97 | end
98 | end
99 | end
100 |
101 | always @(posedge clk) begin
102 | if (reset) begin
103 | `EPC <= 0;
104 | `PrId <= 32'hDEADBEEF;
105 | `IE <= 0;
106 | `EXL <= 1;
107 | `IM <= 6'b111111;
108 | // interruptSource <= 0;
109 | pendingInterrupt <= 0;
110 | clearTimerInterrupt <= 0;
111 | end
112 | else begin
113 | if (isException || !writeEnable || number != `CountNumber) begin
114 | `Count <= `Count + 1;
115 | end
116 |
117 | // interruptSource <= externalInterrupt;
118 | if (hasInterrupt) begin
119 | pendingInterrupt <= 1;
120 | end
121 | else if (pendingInterrupt) begin
122 | if (`EXL) begin
123 | pendingInterrupt <= 0;
124 | end
125 | end
126 | if (isException) begin
127 | if (`EXL) begin
128 | if (exceptionCause == `causeERET) begin
129 | `EXL <= 0;
130 | end
131 | end
132 | else begin
133 | if (exceptionCause != `causeERET) begin
134 | `BadVAddr <= exceptionBadVAddr;
135 | `BD <= isBD;
136 | `ExcCode <= exceptionCause;
137 | if (isBD) begin
138 | `EPC <= exceptionPC - 4;
139 | end
140 | else begin
141 | `EPC <= exceptionPC;
142 | end
143 | `EXL <= 1;
144 | end
145 | end
146 | end
147 | else begin
148 | if (writeEnable) begin
149 | if (number == `CauseNumber) begin // Cause
150 | `Cause[31:16] <= writeData[31:16];
151 | `Cause[9:0] <= writeData[9:0];
152 | end
153 | else begin
154 | registers[number] <= writeData;
155 | end
156 | end
157 |
158 | `Cause[15:10] <= externalInterrupt[15:10];
159 |
160 | if (writeEnable && number == `CompareNumber) begin
161 | clearTimerInterrupt <= 1;
162 | end else if (clearTimerInterrupt) begin
163 | clearTimerInterrupt <= 0;
164 | end
165 | end
166 | end
167 | end
168 |
169 | endmodule
170 |
--------------------------------------------------------------------------------
/controller.sv:
--------------------------------------------------------------------------------
1 | `include "constants.v"
2 |
3 | module Controller (
4 | input [31:0] instruction,
5 | input [31:0] debugPC,
6 | input [2:0] currentStage,
7 | input reset,
8 | input bubble,
9 |
10 | output logic [4:0] regRead1,
11 | output logic [4:0] regRead2,
12 | output logic regRead1Required,
13 | output logic regRead2Required,
14 |
15 | output logic [3:0] mulCtrl,
16 | output mulEnable,
17 | output logic mulOutputSel,
18 |
19 | output logic memLoad,
20 | output logic [1:0] memWidthCtrl,
21 | output logic memReadSignExtend,
22 | output logic memStore,
23 | output logic branch,
24 | output logic [31:0] immediate,
25 | output logic [4:0] destinationRegister,
26 | output logic aluSrc,
27 | output logic [3:0] aluCtrl,
28 | output logic [3:0] cmpCtrl,
29 | output logic absJump,
30 | output logic absJumpLoc, // 1 = immediate, 0 = register
31 | output logic [3:0] grfWriteSource,
32 | output logic checkOverflow,
33 | output logic [2:0] generateException,
34 | output logic writeCP0,
35 | output logic [4:0] numberCP0,
36 |
37 | output logic bye
38 | );
39 |
40 | wire [5:0] opcode = instruction[31:26];
41 | wire [5:0] funct = instruction[5:0];
42 |
43 | wire [4:0] rti = instruction[20:16];
44 | wire [4:0] rsi = instruction[25:21];
45 | wire [4:0] rdi = instruction[15:11];
46 |
47 | wire[25:0] bigImm = instruction[25:0];
48 | wire [15:0] imm = instruction[15:0];
49 | wire [31:0] zeroExtendedImmediate = imm;
50 | wire [31:0] shiftedImmediate = {imm, 16'b0};
51 | wire [31:0] signExtendedImmediate = $signed(imm);
52 |
53 | assign mulEnable = mulCtrl != `mtDisabled;
54 |
55 | localparam reg_ra = 31;
56 |
57 | localparam R = 6'b000000;
58 | localparam REGIMM = 6'b000001;
59 | localparam ori = 6'b001101;
60 | localparam andi = 6'b001100;
61 | localparam xori = 6'b001110;
62 | localparam lw = 6'b100011;
63 | localparam sw = 6'b101011;
64 | localparam beq = 6'b000100;
65 | localparam bne = 6'b000101;
66 | localparam blez = 6'b000110;
67 | localparam bgtz = 6'b000111;
68 | localparam lui = 6'b001111;
69 | localparam jal = 6'b000011;
70 | localparam addiu = 6'b001001;
71 | localparam addi = 6'b001000;
72 | localparam j = 6'b000010;
73 | localparam lb = 6'b100000;
74 | localparam lbu = 6'b100100;
75 | localparam lh = 6'b100001;
76 | localparam lhu = 6'b100101;
77 | localparam sb = 6'b101000;
78 | localparam sh = 6'b101001;
79 | localparam special2 = 6'b011100;
80 | localparam cop0 = 6'b010000;
81 |
82 | localparam addu = 6'b100001;
83 | localparam add = 6'b100000;
84 | localparam subu = 6'b100011;
85 | localparam sub = 6'b100010;
86 | localparam _and = 6'b100100;
87 | localparam _or = 6'b100101;
88 | localparam _xor = 6'b100110;
89 | localparam _nor = 6'b100111;
90 | localparam sll = 6'b000000;
91 | localparam srl = 6'b000010;
92 | localparam sra = 6'b000011;
93 | localparam sllv = 6'b000100;
94 | localparam srlv = 6'b000110;
95 | localparam srav = 6'b000111;
96 | localparam jalr = 6'b001001;
97 | localparam mult = 6'b011000;
98 | localparam multu = 6'b011001;
99 | localparam div = 6'b011010;
100 | localparam divu = 6'b011011;
101 | localparam mfhi = 6'b010000;
102 | localparam mflo = 6'b010010;
103 | localparam mthi = 6'b010001;
104 | localparam mtlo = 6'b010011;
105 | localparam msub = 6'b000100;
106 | localparam madd = 6'b000000;
107 | localparam maddu = 6'b000001;
108 | localparam eret = 6'b011000;
109 |
110 | localparam bltz = 5'b00000;
111 | localparam bgez = 5'b00001;
112 | localparam bltzal = 5'b10000;
113 | localparam bgezal = 5'b10001;
114 |
115 | localparam mfc0 = 5'b00000;
116 | localparam mtc0 = 5'b00100;
117 |
118 | localparam slt = 6'b101010;
119 | localparam sltu = 6'b101011;
120 | localparam slti = 6'b001010;
121 | localparam sltiu = 6'b001011;
122 |
123 | localparam jr = 6'b001000;
124 | localparam syscall = 6'b001100;
125 | localparam _break = 6'b001101;
126 |
127 | localparam debug = 1;
128 |
129 | always_comb begin
130 | regRead1Required = 0;
131 | regRead2Required = 0;
132 | if (currentStage == `stageD) begin
133 | if (absJump || branch) begin
134 | regRead1Required = 1;
135 | regRead2Required = 1;
136 | end
137 | end
138 | else if (currentStage == `stageE) begin
139 | if (aluCtrl != `aluDisabled || mulCtrl != `mtDisabled) begin
140 | regRead1Required = 1;
141 | if (aluSrc == 0)
142 | regRead2Required = 1;
143 | end
144 | end
145 | else if (currentStage == `stageM) begin
146 | if (memStore) begin
147 | regRead2Required = 1;
148 | end
149 | end
150 | else if (currentStage == `stageW) begin
151 | if (writeCP0) begin
152 | regRead1Required = 1;
153 | end
154 | end
155 | end
156 |
157 | `define simpleALU \
158 | regRead1 = rsi; \
159 | regRead2 = rti;\
160 | grfWriteSource = `grfWriteALU; \
161 | destinationRegister = rdi;
162 |
163 | `define simpleShift \
164 | regRead1 = rti; \
165 | grfWriteSource = `grfWriteALU; \
166 | destinationRegister = rdi; \
167 | aluSrc = 1; \
168 | immediate = instruction[10:6];
169 |
170 | `define simpleShiftVariable \
171 | regRead1 = rti; \
172 | regRead2 = rsi; \
173 | grfWriteSource = `grfWriteALU; \
174 | destinationRegister = rdi;
175 |
176 | `define simpleALUImmediate \
177 | regRead1 = rsi; \
178 | grfWriteSource = `grfWriteALU; \
179 | destinationRegister = rti; \
180 | aluSrc = 1;
181 |
182 | `define simpleBranch \
183 | regRead1 = rsi; \
184 | branch = 1; \
185 | immediate = signExtendedImmediate;
186 |
187 | `define simpleMemoryLoad \
188 | regRead1 = rsi; \
189 | memLoad = 1; \
190 | grfWriteSource = `grfWriteMem; \
191 | destinationRegister = rti; \
192 | aluSrc = 1; \
193 | aluCtrl = `aluAdd; \
194 | checkOverflow = 1; \
195 | immediate = signExtendedImmediate;
196 |
197 | `define simpleMemoryStore \
198 | regRead1 = rsi; \
199 | regRead2 = rti; \
200 | memStore = 1; \
201 | aluSrc = 1; \
202 | aluCtrl = `aluAdd; \
203 | checkOverflow = 1; \
204 | immediate = signExtendedImmediate;
205 |
206 | `define simpleMUL \
207 | regRead1 = rsi; \
208 | regRead2 = rti;
209 |
210 | `define simpleLink \
211 | grfWriteSource = `grfWritePC; \
212 | destinationRegister = reg_ra;
213 |
214 | always_comb begin
215 | memLoad = 0;
216 | memStore = 0;
217 | grfWriteSource = `grfWriteDisable;
218 | branch = 0;
219 | destinationRegister = 0;
220 | aluSrc = 0;
221 | aluCtrl = `aluDisabled;
222 | absJump = 0;
223 | regRead1 = 0;
224 | bye = 0;
225 | regRead2 = 0;
226 | memWidthCtrl = 0;
227 | memReadSignExtend = 0;
228 | checkOverflow = 0;
229 | mulOutputSel = 'bx;
230 | mulCtrl = `mtDisabled;
231 | generateException = `ctrlNoException;
232 | writeCP0 = 0;
233 | numberCP0 = 0;
234 | `ifdef DEBUG
235 |
236 | immediate = 'bx;
237 | absJumpLoc = 'bx;
238 | `else
239 | immediate = 0;
240 | absJumpLoc = 0;
241 | `endif
242 |
243 | if (!reset && !bubble)
244 | case (opcode)
245 | cop0: begin
246 | case (funct)
247 | 6'b000000: begin
248 | case (rsi)
249 | mfc0: begin
250 | destinationRegister = rti;
251 | grfWriteSource = `grfWriteCP0;
252 | numberCP0 = rdi;
253 | end
254 | mtc0: begin
255 | regRead1 = rti;
256 | writeCP0 = 1;
257 | numberCP0 = rdi;
258 | end
259 | endcase
260 | end
261 | eret: begin
262 | generateException = `ctrlERET;
263 | end
264 | default: begin
265 | generateException = `ctrlUnknownInstruction;
266 | end
267 | endcase
268 | end
269 | special2: begin
270 | case (funct)
271 | msub: begin
272 | `simpleMUL
273 | mulCtrl = `mtMSUB;
274 | end
275 | madd: begin
276 | `simpleMUL
277 | mulCtrl = `mtMADD;
278 | end
279 | maddu: begin
280 | `simpleMUL
281 | mulCtrl = `mtMADDU;
282 | end
283 | default: begin
284 | generateException = `ctrlUnknownInstruction;
285 | end
286 | endcase
287 | end
288 |
289 | REGIMM: begin
290 | case (rti)
291 | bltzal: begin
292 | `simpleBranch
293 | `simpleLink
294 | cmpCtrl = `cmpLessThanZero;
295 | end
296 | bgezal: begin
297 | `simpleBranch
298 | `simpleLink
299 | cmpCtrl = `cmpGreaterThanOrEqualToZero;
300 | end
301 | bltz: begin
302 | `simpleBranch
303 | cmpCtrl = `cmpLessThanZero;
304 | end
305 | bgez: begin
306 | `simpleBranch
307 | cmpCtrl = `cmpGreaterThanOrEqualToZero;
308 | end
309 |
310 | default: begin
311 | generateException = `ctrlUnknownInstruction;
312 | end
313 | endcase
314 | end
315 |
316 | R: begin
317 | case(funct)
318 | addu: begin
319 | `simpleALU
320 | aluCtrl = `aluAdd;
321 | end
322 | subu: begin
323 | `simpleALU
324 | aluCtrl = `aluSub;
325 | end
326 | add: begin
327 | `simpleALU
328 | aluCtrl = `aluAdd;
329 | checkOverflow = 1;
330 | end
331 | sub: begin
332 | `simpleALU
333 | aluCtrl = `aluSub;
334 | checkOverflow = 1;
335 | end
336 |
337 | _and: begin
338 | `simpleALU
339 | aluCtrl = `aluAnd;
340 | end
341 | _or: begin
342 | `simpleALU
343 | aluCtrl = `aluOr;
344 | end
345 | _nor: begin
346 | `simpleALU
347 | aluCtrl = `aluNor;
348 | end
349 | _xor: begin
350 | `simpleALU
351 | aluCtrl = `aluXor;
352 | end
353 |
354 | sll: begin
355 | `simpleShift
356 | aluCtrl = `aluShiftLeft;
357 | end
358 | srl: begin
359 | `simpleShift
360 | aluCtrl = `aluShiftRight;
361 | end
362 | sra: begin
363 | `simpleShift
364 | aluCtrl = `aluArithmeticShiftRight;
365 | end
366 |
367 | sllv: begin
368 | `simpleShiftVariable
369 | aluCtrl = `aluShiftLeft;
370 | end
371 | srlv: begin
372 | `simpleShiftVariable
373 | aluCtrl = `aluShiftRight;
374 | end
375 | srav: begin
376 | `simpleShiftVariable
377 | aluCtrl = `aluArithmeticShiftRight;
378 | end
379 |
380 | slt: begin
381 | `simpleALU
382 | aluCtrl = `aluSLT;
383 | end
384 |
385 | sltu: begin
386 | `simpleALU
387 | aluCtrl = `aluSLTU;
388 | end
389 |
390 | jr: begin
391 | regRead1 = rsi;
392 | absJump = 1;
393 | absJumpLoc = `absJumpRegister;
394 | end
395 |
396 | jalr: begin
397 | regRead1 = rsi;
398 | absJump = 1;
399 | absJumpLoc = `absJumpRegister;
400 | grfWriteSource = `grfWritePC;
401 | destinationRegister = rdi;
402 | end
403 |
404 | syscall: begin
405 | generateException = `ctrlSyscall;
406 | end
407 |
408 | _break: begin
409 | generateException = `ctrlBreak;
410 | end
411 |
412 | mult: begin
413 | `simpleMUL
414 | mulCtrl = `mtMultiply;
415 | end
416 |
417 | multu: begin
418 | `simpleMUL
419 | mulCtrl = `mtMultiplyUnsigned;
420 | end
421 |
422 | div: begin
423 | `simpleMUL
424 | mulCtrl = `mtDivide;
425 | end
426 |
427 | divu: begin
428 | `simpleMUL
429 | mulCtrl = `mtDivideUnsigned;
430 | end
431 |
432 | mfhi: begin
433 | mulOutputSel = 1;
434 | destinationRegister = rdi;
435 | grfWriteSource = `grfWriteMul;
436 | end
437 |
438 | mflo: begin
439 | mulOutputSel = 0;
440 | destinationRegister = rdi;
441 | grfWriteSource = `grfWriteMul;
442 | end
443 |
444 | mthi: begin
445 | regRead1 = rsi;
446 | mulCtrl = `mtSetHI;
447 | end
448 |
449 | mtlo: begin
450 | regRead1 = rsi;
451 | mulCtrl = `mtSetLO;
452 | end
453 |
454 | default: begin
455 | generateException = `ctrlUnknownInstruction;
456 | end
457 | endcase
458 | end
459 |
460 | addiu: begin
461 | `simpleALUImmediate
462 | immediate = signExtendedImmediate;
463 | aluCtrl = `aluAdd;
464 | end
465 |
466 | addi: begin
467 | `simpleALUImmediate
468 | immediate = signExtendedImmediate;
469 | aluCtrl = `aluAdd;
470 | checkOverflow = 1;
471 | end
472 |
473 | ori: begin
474 | `simpleALUImmediate
475 | immediate = zeroExtendedImmediate;
476 | aluCtrl = `aluOr;
477 | end
478 |
479 | xori: begin
480 | `simpleALUImmediate
481 | immediate = zeroExtendedImmediate;
482 | aluCtrl = `aluXor;
483 | end
484 |
485 | andi: begin
486 | `simpleALUImmediate
487 | immediate = zeroExtendedImmediate;
488 | aluCtrl = `aluAnd;
489 | end
490 |
491 | slti: begin
492 | `simpleALUImmediate
493 | immediate = signExtendedImmediate;
494 | aluCtrl = `aluSLT;
495 | end
496 |
497 | sltiu: begin
498 | `simpleALUImmediate
499 | immediate = signExtendedImmediate;
500 | aluCtrl = `aluSLTU;
501 | end
502 |
503 | lw: begin
504 | `simpleMemoryLoad
505 | memWidthCtrl = `memWidth4;
506 | end
507 |
508 | lh: begin
509 | `simpleMemoryLoad
510 | memWidthCtrl = `memWidth2;
511 | memReadSignExtend = 1;
512 | end
513 |
514 | lb: begin
515 | `simpleMemoryLoad
516 | memWidthCtrl = `memWidth1;
517 | memReadSignExtend = 1;
518 | end
519 |
520 | lhu: begin
521 | `simpleMemoryLoad
522 | memWidthCtrl = `memWidth2;
523 | memReadSignExtend = 0;
524 | end
525 |
526 | lbu: begin
527 | `simpleMemoryLoad
528 | memWidthCtrl = `memWidth1;
529 | memReadSignExtend = 0;
530 | end
531 |
532 | sw: begin
533 | `simpleMemoryStore
534 | memWidthCtrl = `memWidth4;
535 | end
536 |
537 | sh: begin
538 | `simpleMemoryStore
539 | memWidthCtrl = `memWidth2;
540 | end
541 |
542 | sb: begin
543 | `simpleMemoryStore
544 | memWidthCtrl = `memWidth1;
545 | end
546 |
547 | beq: begin
548 | `simpleBranch
549 | regRead2 = rti;
550 | cmpCtrl = `cmpEqual;
551 | end
552 |
553 | bne: begin
554 | `simpleBranch
555 | regRead2 = rti;
556 | cmpCtrl = `cmpNotEqual;
557 | end
558 |
559 | blez: begin
560 | `simpleBranch
561 | cmpCtrl = `cmpLessThanOrEqualToZero;
562 | end
563 |
564 | bgtz: begin
565 | `simpleBranch
566 | cmpCtrl = `cmpGreaterThanZero;
567 | end
568 |
569 |
570 | lui: begin
571 | regRead1 = rsi;
572 | grfWriteSource = `grfWriteALU;
573 | destinationRegister = rti;
574 | aluSrc = 1;
575 | aluCtrl = `aluAdd;
576 | immediate = shiftedImmediate;
577 | end
578 |
579 | jal: begin
580 | absJump = 1;
581 | absJumpLoc = `absJumpImmediate;
582 | immediate = bigImm;
583 | `simpleLink
584 | end
585 |
586 | j: begin
587 | absJump = 1;
588 | absJumpLoc = `absJumpImmediate;
589 | immediate = bigImm;
590 | end
591 |
592 | default: begin
593 | generateException = `ctrlUnknownInstruction;
594 | end
595 | endcase
596 | end
597 |
598 | endmodule
--------------------------------------------------------------------------------
/cpu.v:
--------------------------------------------------------------------------------
1 | `include "constants.v"
2 | module CPU (
3 | input clk,
4 | input reset,
5 | input [5:0] irq,
6 |
7 | output [31:0] inst_sram_addr,
8 | input [31:0] inst_sram_rdata,
9 |
10 | output data_sram_en,
11 | output [3:0] data_sram_wen,
12 | output [31:0] data_sram_addr,
13 | output [31:0] data_sram_wdata,
14 | input [31:0] data_sram_rdata,
15 |
16 | output [31:0] debug_wb_pc,
17 | output [3:0] debug_wb_rf_wen,
18 | output [4:0] debug_wb_rf_wnum,
19 | output [31:0] debug_wb_rf_wdata
20 | );
21 |
22 | reg [31:0] effectivePC;
23 |
24 | reg [31:0] W_pc;
25 | wire D_data_waiting;
26 | wire E_data_waiting;
27 | wire M_data_waiting;
28 | reg [2:0] stallLevel;
29 | always @(*) begin
30 | stallLevel = `stallNone;
31 | if (D_data_waiting) begin
32 | stallLevel = `stallDecode;
33 | end
34 | if (E_data_waiting) begin
35 | stallLevel = `stallExecution;
36 | end
37 | if (M_data_waiting) begin
38 | stallLevel = `stallMemory;
39 | end
40 | end
41 |
42 | reg [2:0] exceptionLevel;
43 | wire F_exception;
44 | reg D_exception;
45 | reg E_exception;
46 | reg M_exception;
47 | wire W_exception;
48 |
49 | always @(*) begin
50 | exceptionLevel = `stallNone;
51 | if (F_exception) begin
52 | exceptionLevel = `stallFetch;
53 | end
54 | if (D_exception) begin
55 | exceptionLevel = `stallDecode;
56 | end
57 | if (E_exception) begin
58 | exceptionLevel = `stallExecution;
59 | end
60 | if (M_exception) begin
61 | exceptionLevel = `stallMemory;
62 | end
63 | if (W_exception) begin
64 | exceptionLevel = `stallWriteBack;
65 | end
66 | end
67 |
68 | CP0 cp0(
69 | .clk(clk),
70 | .reset(reset),
71 | .externalInterrupt(irq),
72 | .hasExceptionInPipeline(exceptionLevel >= `stallMemory)
73 | );
74 |
75 | // Forwarding logic:
76 | // If forward source is non-zero, it means that a value to be written is already in the pipeline
77 | // which is either available or non-available.
78 | // If the value to be read is not available (e.g. to be read from memory), we set valid flag to zero. This means
79 | // a data hazard, and a bubble should be inserted to the pipeline.
80 | // Otherwise the data is forwarded, and no stalling is created.
81 |
82 | wire forwardValidE;
83 | wire [4:0] forwardAddressE;
84 | wire [31:0] forwardValueE;
85 |
86 | // From ALU, in Memory
87 | wire forwardValidM;
88 | wire [4:0] forwardAddressM;
89 | wire [31:0] forwardValueM;
90 |
91 | // From Write
92 | wire forwardValidW;
93 | wire [4:0] forwardAddressW;
94 | wire [31:0] forwardValueW;
95 |
96 | // ======== Fetch Stage ========
97 | reg F_jump;
98 | reg [31:0] F_jumpAddr;
99 | wire F_stall = stallLevel >= `stallFetch;
100 | reg F_isDelaySlot;
101 |
102 | InstructionMemory F_im (
103 | .clk(clk),
104 | .reset(reset),
105 | .inst_sram_rdata(inst_sram_rdata),
106 | .inst_sram_addr(inst_sram_addr),
107 | .absJump(F_jump),
108 | .absJumpAddress(F_jumpAddr),
109 | .pcStall(F_stall),
110 | .hang(exceptionLevel >= `stallFetch)
111 | );
112 |
113 | assign F_exception = F_im.exception;
114 | wire F_insert_bubble = F_im.bubble;
115 | wire [4:0] F_cause = F_im.exception ? `causeAdEL : 'bx;
116 | wire [31:0] F_badVAddr = F_im.exception ? F_im.outputPC : 'bx;
117 |
118 | // ======== Decode Stage ========
119 | wire D_stall = stallLevel >= `stallDecode;
120 | reg D_last_bubble;
121 | wire D_insert_bubble = D_last_bubble || D_data_waiting;
122 | reg [31:0] D_currentInstruction;
123 | reg [31:0] D_pc;
124 | reg D_last_exception;
125 | reg D_isDelaySlot;
126 | reg [4:0] D_last_cause;
127 | reg [31:0] D_badVAddr;
128 |
129 | always @(posedge clk) begin
130 | if (reset) begin
131 | D_last_bubble <= 1;
132 | D_last_exception <= 0;
133 | D_pc <= 0;
134 | D_isDelaySlot <= 0;
135 | D_badVAddr <= 0;
136 | D_currentInstruction <= 0;
137 | end
138 | else begin
139 | if (cp0.interruptNow) begin
140 | D_last_bubble <= 1;
141 | D_last_exception <= 0;
142 | D_pc <= 0;
143 | D_isDelaySlot <= 0;
144 | end
145 | else begin
146 | D_last_bubble <= F_insert_bubble || exceptionLevel >= `stallDecode;
147 | if (!D_stall) begin
148 | D_badVAddr <= F_badVAddr;
149 | D_isDelaySlot <= F_isDelaySlot;
150 | D_last_exception <= F_exception;
151 | D_last_cause <= F_cause;
152 | D_currentInstruction <= F_im.instruction;
153 | D_pc <= F_im.outputPC;
154 | end
155 | end
156 | end
157 | end
158 |
159 | Controller D_ctrl(
160 | .instruction(D_currentInstruction),
161 | .reset(reset),
162 | .currentStage(`stageD),
163 | .bubble(D_last_bubble || D_last_exception),
164 | .debugPC(D_pc)
165 | );
166 |
167 | reg [4:0] D_cause;
168 | always @(*) begin
169 | D_cause = 'bx;
170 | D_exception = 0;
171 | if (D_last_bubble) begin
172 | D_exception = 0;
173 | end
174 | else if (D_last_exception) begin
175 | D_cause = D_last_cause;
176 | D_exception = 1;
177 | end
178 | else begin
179 | case (D_ctrl.generateException)
180 | `ctrlUnknownInstruction: begin
181 | D_cause = `causeRI;
182 | D_exception = 1;
183 | end
184 | `ctrlERET: begin
185 | D_cause = `causeERET;
186 | D_exception = 1;
187 | end
188 | `ctrlSyscall: begin
189 | D_cause = `causeSyscall;
190 | D_exception = 1;
191 | end
192 | `ctrlBreak: begin
193 | D_cause = `causeBreak;
194 | D_exception = 1;
195 | end
196 | endcase
197 | end
198 | end
199 |
200 | reg [4:0] grfWriteAddress;
201 | reg [31:0] grfWriteData;
202 | GeneralRegisterFile D_grf(
203 | .clk(clk),
204 | .reset(reset),
205 | .writeData(grfWriteData),
206 | .writeAddress(grfWriteAddress), // set to 0 if no write operation shall be performed
207 |
208 | .readAddress1(D_ctrl.regRead1),
209 | .readAddress2(D_ctrl.regRead2),
210 | .debugPC(W_pc)
211 | );
212 |
213 | assign debug_wb_pc = W_pc;
214 | assign debug_wb_rf_wen = grfWriteAddress != 0 ? 4'b1111 : 0;
215 | assign debug_wb_rf_wnum = grfWriteAddress;
216 | assign debug_wb_rf_wdata = grfWriteData;
217 |
218 | ForwardController D_regRead1_forward (
219 | .request(D_ctrl.regRead1),
220 | .original(D_grf.readOutput1),
221 | .enabled(D_ctrl.regRead1Required),
222 | .debugPC(D_pc),
223 | .debugStage("D"),
224 |
225 | .src1Valid(forwardValidE),
226 | .src1Reg(forwardAddressE),
227 | .src1Value(forwardValueE),
228 | .src2Valid(forwardValidM),
229 | .src2Reg(forwardAddressM),
230 | .src2Value(forwardValueM),
231 | .src3Valid(forwardValidW),
232 | .src3Reg(forwardAddressW),
233 | .src3Value(forwardValueW)
234 | );
235 |
236 | ForwardController D_regRead2_forward (
237 | .request(D_ctrl.regRead2),
238 | .original(D_grf.readOutput2),
239 | .enabled(D_ctrl.regRead2Required),
240 | .debugPC(D_pc),
241 | .debugStage("D"),
242 |
243 | .src1Valid(forwardValidE),
244 | .src1Reg(forwardAddressE),
245 | .src1Value(forwardValueE),
246 | .src2Valid(forwardValidM),
247 | .src2Reg(forwardAddressM),
248 | .src2Value(forwardValueM),
249 | .src3Valid(forwardValidW),
250 | .src3Reg(forwardAddressW),
251 | .src3Value(forwardValueW)
252 | );
253 |
254 | assign D_data_waiting = D_regRead1_forward.stallExec || D_regRead2_forward.stallExec;
255 |
256 | Comparator cmp(
257 | .A(D_regRead1_forward.value),
258 | .B(D_regRead2_forward.value),
259 | .ctrl(D_ctrl.cmpCtrl)
260 | );
261 | always @(*) begin
262 | F_jump = 0;
263 | F_jumpAddr = 0;
264 | F_isDelaySlot = 0;
265 | if (cp0.jump) begin
266 | F_jump = 1;
267 | F_jumpAddr = cp0.jumpAddress;
268 | end
269 | else if (D_ctrl.branch) begin
270 | F_isDelaySlot = 1;
271 | F_jump = cmp.action;
272 | F_jumpAddr = D_pc + 4 + (D_ctrl.immediate << 2);
273 | end
274 | else if (D_ctrl.absJump) begin
275 | F_isDelaySlot = 1;
276 | F_jump = 1;
277 | if (D_ctrl.absJumpLoc == `absJumpImmediate) begin
278 | F_jumpAddr = {D_pc[31:28], D_ctrl.immediate[25:0], 2'b00};
279 | end
280 | else begin
281 | F_jumpAddr = D_regRead1_forward.value;
282 | end
283 | end
284 | end
285 |
286 | reg [31:0] D_real_pc;
287 | always @(*) begin
288 | if (D_last_bubble) begin
289 | D_real_pc <= F_im.pc;
290 | end else begin
291 | D_real_pc <= D_pc;
292 | end
293 | end
294 |
295 | // ======== Execution Stage ========
296 |
297 | wire E_stall = stallLevel >= `stallExecution;
298 | reg E_bubble;
299 | wire E_insert_bubble = E_bubble || E_data_waiting;
300 | reg [31:0] E_currentInstruction;
301 | reg [31:0] E_pc;
302 | reg [31:0] E_regRead1;
303 | reg [31:0] E_regRead2;
304 |
305 | reg E_regWriteDataValid;
306 | reg [31:0] E_regWriteData;
307 |
308 | reg E_last_exception;
309 | reg [4:0] E_last_cause;
310 | reg [31:0] E_badVAddr;
311 |
312 | reg E_isDelaySlot;
313 |
314 | assign forwardValidE = E_regWriteDataValid;
315 | assign forwardAddressE = E_ctrl.destinationRegister;
316 | assign forwardValueE = E_regWriteData;
317 |
318 | always @(*) begin
319 | E_regWriteDataValid = 0;
320 | E_regWriteData = 'bx;
321 | case (E_ctrl.grfWriteSource)
322 | `grfWritePC: begin
323 | E_regWriteData = E_pc + 8;
324 | E_regWriteDataValid = 1;
325 | end
326 | endcase
327 | end
328 |
329 | always @(posedge clk) begin
330 | if (reset) begin
331 | E_bubble <= 1;
332 | E_last_exception <= 0;
333 | E_pc <= 0;
334 | E_regRead1 <= 0;
335 | E_regRead2 <= 0;
336 | E_badVAddr <= 0;
337 | E_isDelaySlot <= 0;
338 | end
339 | else begin
340 | if (cp0.interruptNow) begin
341 | E_bubble <= 1;
342 | E_last_exception <= 0;
343 | E_pc <= 0;
344 | E_isDelaySlot <= 0;
345 | end
346 | else if (!E_stall) begin
347 | E_last_exception <= D_exception;
348 | E_last_cause <= D_cause;
349 | E_bubble <= D_insert_bubble || exceptionLevel >= `stallExecution;
350 | E_currentInstruction <= D_currentInstruction;
351 | E_pc <= D_real_pc;
352 | E_regRead1 <= D_regRead1_forward.value;
353 | E_regRead2 <= D_regRead2_forward.value;
354 | E_isDelaySlot <= D_isDelaySlot;
355 | E_badVAddr <= D_badVAddr;
356 | end
357 | else begin
358 | E_bubble <= E_bubble || exceptionLevel >= `stallExecution;
359 | E_regRead1 <= E_regRead1_forward.value;
360 | E_regRead2 <= E_regRead2_forward.value;
361 | end
362 | end
363 | end
364 |
365 | Controller E_ctrl(
366 | .instruction(E_currentInstruction),
367 | .reset(reset),
368 | .currentStage(`stageE),
369 | .bubble(E_bubble || E_last_exception),
370 | .debugPC(E_pc)
371 | );
372 |
373 |
374 | ForwardController E_regRead1_forward (
375 | .request(E_ctrl.regRead1),
376 | .original(E_regRead1),
377 | .enabled(E_ctrl.regRead1Required),
378 | .debugPC(E_pc),
379 | .debugStage("E"),
380 |
381 | .src1Valid(forwardValidM),
382 | .src1Reg(forwardAddressM),
383 | .src1Value(forwardValueM),
384 |
385 | .src2Valid(forwardValidW),
386 | .src2Reg(forwardAddressW),
387 | .src2Value(forwardValueW),
388 |
389 | .src3Reg(5'b0)
390 | );
391 |
392 | ForwardController E_regRead2_forward (
393 | .request(E_ctrl.regRead2),
394 | .original(E_regRead2),
395 | .enabled(E_ctrl.regRead2Required),
396 | .debugPC(E_pc),
397 | .debugStage("E"),
398 |
399 | .src1Valid(forwardValidM),
400 | .src1Reg(forwardAddressM),
401 | .src1Value(forwardValueM),
402 |
403 | .src2Valid(forwardValidW),
404 | .src2Reg(forwardAddressW),
405 | .src2Value(forwardValueW),
406 |
407 | .src3Reg(5'b0)
408 | );
409 |
410 | ArithmeticLogicUnit E_alu(
411 | .ctrl(E_ctrl.aluCtrl),
412 | .A(E_regRead1_forward.value),
413 | .B(E_ctrl.aluSrc ? E_ctrl.immediate : E_regRead2_forward.value)
414 | );
415 |
416 | reg [4:0] E_cause;
417 | always @(*) begin
418 | E_cause = 'bx;
419 | E_exception = 0;
420 | if (E_bubble) begin
421 | E_exception = 0;
422 | end
423 | else if (E_last_exception) begin
424 | E_cause = E_last_cause;
425 | E_exception = 1;
426 | end
427 | else if (E_ctrl.checkOverflow && E_alu.overflow) begin
428 | if (E_ctrl.memLoad) begin
429 | E_cause = `causeAdEL;
430 | E_exception = 1;
431 | end
432 | else if (E_ctrl.memStore) begin
433 | E_cause = `causeAdES;
434 | E_exception = 1;
435 | end
436 | else begin
437 | E_cause = `causeOv;
438 | E_exception = 1;
439 | end
440 | end
441 | end
442 |
443 | reg E_mul_collision;
444 | assign E_data_waiting = E_regRead1_forward.stallExec || E_regRead2_forward.stallExec || E_mul_collision;
445 | reg E_mulStart;
446 |
447 | always @(*) begin
448 | E_mulStart = 0;
449 | E_mul_collision = 0;
450 | if (E_ctrl.mulEnable || E_ctrl.grfWriteSource == `grfWriteMul) begin
451 | if (E_mul.busy) begin
452 | E_mul_collision = 1;
453 | end
454 | else if (E_ctrl.mulEnable && !M_exception) begin
455 | E_mulStart = 1;
456 | end
457 | end
458 | end
459 |
460 | Multiplier E_mul(
461 | .ctrl(E_ctrl.mulCtrl),
462 | .start(!E_data_waiting && E_mulStart),
463 | .reset(reset),
464 | .clk(clk),
465 | .A(E_regRead1_forward.value),
466 | .B(E_ctrl.aluSrc ? E_ctrl.immediate : E_regRead2_forward.value)
467 | );
468 |
469 | wire [31:0] E_mul_value = E_ctrl.mulOutputSel ? E_mul.HI : E_mul.LO;
470 |
471 | reg [31:0] E_real_pc;
472 |
473 | always @(*) begin
474 | if (E_bubble) begin
475 | E_real_pc <= D_real_pc;
476 | end else begin
477 | E_real_pc <= E_pc;
478 | end
479 | end
480 |
481 | // ======== Memory Stage ========
482 |
483 | wire M_stall = stallLevel >= `stallMemory;
484 | reg M_bubble;
485 | wire M_insert_bubble = M_bubble || M_data_waiting;
486 | reg [31:0] M_currentInstruction;
487 | reg [31:0] M_pc;
488 | reg [31:0] M_aluOutput;
489 | reg [31:0] M_mulOutput;
490 | reg [31:0] M_regRead1;
491 | reg [31:0] M_regRead2;
492 | reg [31:0] M_lastBadVAddr;
493 | reg M_lastWriteDataValid;
494 | reg [31:0] M_lastWriteData;
495 |
496 | reg M_regWriteDataValid;
497 | reg [31:0] M_regWriteData;
498 | reg M_last_exception;
499 | reg [4:0] M_last_cause;
500 | reg [31:0] M_badVAddr;
501 |
502 | reg M_isDelaySlot;
503 |
504 | always @(posedge clk) begin
505 | if (reset) begin
506 | M_bubble <= 1;
507 | M_last_exception <= 0;
508 | M_currentInstruction <= 0;
509 | M_pc <= 0;
510 | M_aluOutput <= 0;
511 | M_lastBadVAddr <= 0;
512 | M_mulOutput <= 0;
513 | M_regRead1 <= 0;
514 | M_regRead2 <= 0;
515 | M_lastWriteDataValid <= 0;
516 | M_lastWriteData <= 0;
517 | M_isDelaySlot <= 0;
518 | end
519 | else begin
520 | if (cp0.interruptNow) begin
521 | M_bubble <= 0;
522 | M_last_exception <= 1;
523 | M_last_cause <= `causeInt;
524 | M_pc <= E_real_pc;
525 | M_isDelaySlot <= E_isDelaySlot;
526 | end
527 | else if (!M_stall) begin
528 | M_bubble <= E_insert_bubble || exceptionLevel >= `stallMemory;
529 | M_last_exception <= E_exception;
530 | M_last_cause <= E_cause;
531 | M_currentInstruction <= E_currentInstruction;
532 | M_pc <= E_real_pc;
533 | M_aluOutput <= E_alu.out;
534 | M_lastBadVAddr <= E_badVAddr;
535 | M_mulOutput <= E_mul_value;
536 | M_regRead1 <= E_regRead1_forward.value;
537 | M_regRead2 <= E_regRead2_forward.value;
538 | M_lastWriteDataValid <= E_regWriteDataValid;
539 | M_lastWriteData <= E_regWriteData;
540 | M_isDelaySlot <= E_isDelaySlot;
541 | end
542 | else begin
543 | M_bubble <= M_bubble || exceptionLevel >= `stallMemory;
544 | M_regRead1 <= M_regRead1_forward.value;
545 | M_regRead2 <= M_regRead2_forward.value;
546 | end
547 | end
548 | end
549 |
550 | assign forwardAddressM = M_ctrl.destinationRegister;
551 | assign forwardValueM = M_regWriteData;
552 | assign forwardValidM = M_regWriteDataValid;
553 | always @(*) begin
554 | if (M_lastWriteDataValid) begin
555 | M_regWriteData = M_lastWriteData;
556 | M_regWriteDataValid = 1;
557 | end
558 | else begin
559 | M_regWriteDataValid = 0;
560 | M_regWriteData = 'bx;
561 | case (M_ctrl.grfWriteSource)
562 | `grfWriteALU: begin
563 | M_regWriteData = M_aluOutput;
564 | M_regWriteDataValid = 1;
565 | end
566 | `grfWriteMul: begin
567 | M_regWriteData = M_mulOutput;
568 | M_regWriteDataValid = 1;
569 | end
570 | endcase
571 | end
572 | end
573 |
574 | Controller M_ctrl(
575 | .instruction(M_currentInstruction),
576 | .reset(reset),
577 | .currentStage(`stageM),
578 | .bubble(M_bubble || M_last_exception),
579 | .debugPC(M_pc)
580 | );
581 |
582 | ForwardController M_regRead1_forward (
583 | .request(M_ctrl.regRead1),
584 | .original(M_regRead1),
585 | .enabled(M_ctrl.regRead1Required),
586 | .debugPC(M_pc),
587 | .debugStage("M"),
588 |
589 | .src1Valid(forwardValidW),
590 | .src1Reg(forwardAddressW),
591 | .src1Value(forwardValueW),
592 |
593 | .src2Reg(5'b0),
594 | .src3Reg(5'b0)
595 | );
596 |
597 | ForwardController M_regRead2_forward (
598 | .request(M_ctrl.regRead2),
599 | .original(M_regRead2),
600 | .enabled(M_ctrl.regRead2Required),
601 | .debugPC(M_pc),
602 | .debugStage("M"),
603 |
604 | .src1Valid(forwardValidW),
605 | .src1Reg(forwardAddressW),
606 | .src1Value(forwardValueW),
607 |
608 | .src2Reg(5'b0),
609 | .src3Reg(5'b0)
610 | );
611 |
612 | assign M_data_waiting = M_regRead1_forward.stallExec || M_regRead2_forward.stallExec;
613 |
614 | DataMemory M_dm(
615 | .clk(clk),
616 | .reset(reset),
617 | .writeEnable(!M_data_waiting && M_ctrl.memStore),
618 | .readEnable(!M_data_waiting && M_ctrl.memLoad),
619 | .address(M_aluOutput),
620 | .writeDataIn(M_regRead2_forward.value), // register@regRead2
621 | .widthCtrl(M_ctrl.memWidthCtrl),
622 |
623 | .data_sram_en(data_sram_en),
624 | .data_sram_wen(data_sram_wen),
625 | .data_sram_addr(data_sram_addr),
626 | .data_sram_wdata(data_sram_wdata)
627 | );
628 |
629 | reg [4:0] M_cause;
630 | always @(*) begin
631 | M_exception = 0;
632 | M_cause = 'bx;
633 | M_badVAddr = M_lastBadVAddr;
634 | if (M_bubble) begin
635 | M_exception = 0;
636 | end
637 | else if (M_last_exception) begin
638 | M_exception = 1;
639 | M_cause = M_last_cause;
640 | end
641 | else if (M_dm.exception) begin
642 | M_exception = 1;
643 | if (M_ctrl.memLoad) begin
644 | M_cause = `causeAdEL;
645 | M_badVAddr = M_aluOutput;
646 | end
647 | else if (M_ctrl.memStore) begin
648 | M_cause = `causeAdES;
649 | M_badVAddr = M_aluOutput;
650 | end
651 | end
652 | end
653 |
654 | // ======== WriteBack Stage ========
655 |
656 | reg [31:0] W_currentInstruction;
657 | reg [31:0] W_aluOutput;
658 | reg [31:0] W_regRead1;
659 | reg W_lastWriteDataValid;
660 | reg [31:0] W_lastWriteData;
661 | reg W_last_exception;
662 | reg [4:0] W_last_cause;
663 | reg [31:0] W_badVAddr;
664 |
665 | reg W_bubble;
666 | reg W_isDelaySlot;
667 | always @(posedge clk) begin
668 | if (reset) begin
669 | W_bubble <= 1;
670 | W_currentInstruction <= 0;
671 | W_pc <= 0;
672 | W_aluOutput <= 0;
673 | W_lastWriteData <= 0;
674 | W_lastWriteDataValid <= 0;
675 | W_last_exception <= 0;
676 | W_badVAddr <= 0;
677 | end
678 | else begin
679 | W_regRead1 <= M_regRead1_forward.value;
680 | W_bubble <= M_insert_bubble;
681 | W_currentInstruction <= M_currentInstruction;
682 | W_pc <= M_pc;
683 | W_aluOutput <= M_aluOutput;
684 | W_lastWriteData <= M_regWriteData;
685 | W_lastWriteDataValid <= M_regWriteDataValid;
686 | W_isDelaySlot <= M_isDelaySlot;
687 | W_badVAddr <= M_badVAddr;
688 | if (M_exception) begin
689 | $display("Exception occurred at %h, caused by %d", M_pc, M_cause);
690 | end
691 | W_last_exception <= M_exception;
692 | W_last_cause <= M_cause;
693 | end
694 | end
695 |
696 | DataMemoryReader W_reader(
697 | .data_sram_rdata(data_sram_rdata),
698 | .readEnable(W_ctrl.memLoad),
699 | .address(W_aluOutput),
700 | .widthCtrl(W_ctrl.memWidthCtrl),
701 | .extendCtrl(W_ctrl.memReadSignExtend)
702 | );
703 |
704 | assign W_exception = !W_bubble && W_last_exception;
705 | assign cp0.isException = W_exception;
706 | assign cp0.exceptionPC = W_pc;
707 | assign cp0.exceptionCause = W_last_cause;
708 |
709 | Controller W_ctrl(
710 | .instruction(W_currentInstruction),
711 | .reset(reset),
712 | .currentStage(`stageW),
713 | .bubble(W_bubble || W_last_exception),
714 | .debugPC(W_pc)
715 | );
716 |
717 | assign cp0.writeEnable = W_ctrl.writeCP0;
718 | assign cp0.number = W_ctrl.numberCP0;
719 | assign cp0.writeData = W_regRead1;
720 | assign cp0.isBD = W_isDelaySlot;
721 | assign cp0.exceptionBadVAddr = W_badVAddr;
722 |
723 | assign forwardValidW = 1;
724 | assign forwardAddressW = W_ctrl.destinationRegister;
725 | assign forwardValueW = grfWriteData;
726 |
727 | always @(*) begin
728 | grfWriteAddress = W_ctrl.destinationRegister;
729 | if (W_lastWriteDataValid) begin
730 | grfWriteData = W_lastWriteData;
731 | end
732 | else begin
733 | grfWriteData = 'bx;
734 | case (W_ctrl.grfWriteSource)
735 | `grfWriteMem: begin
736 | grfWriteData = W_reader.readData;
737 | end
738 | `grfWriteCP0: begin
739 | grfWriteData = cp0.readData;
740 | end
741 | endcase
742 | end
743 | end
744 |
745 | always @(*) begin
746 | effectivePC = 0;
747 | if (!W_bubble && W_exception) begin
748 | effectivePC = W_pc;
749 | end
750 | else if (!M_bubble && M_exception) begin
751 | effectivePC = M_pc;
752 | end
753 | else if (!E_bubble) begin
754 | effectivePC = E_pc;
755 | end
756 | else if (!D_last_bubble) begin
757 | effectivePC = D_pc;
758 | end else begin
759 | effectivePC = F_im.pc;
760 | end
761 | /*
762 | if (exceptionLevel <= `stallExecution) begin
763 | if (!E_bubble) begin
764 | effectivePC = E_pc;
765 | end
766 | else begin
767 | effectivePC = D_pc;
768 | end
769 | end
770 | else begin
771 | if (!M_bubble) begin
772 | effectivePC = M_pc;
773 | end
774 | else begin
775 | effectivePC = W_pc;
776 | end
777 | end
778 | */
779 | end
780 |
781 | endmodule
782 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------