kpmy преди 2 години
родител
ревизия
874a6024c1
променени са 32 файла, в които са добавени 1675 реда и са изтрити 0 реда
  1. 13 0
      people.inf.ethz.ch/wirth/FPGA-relatedWork/DRAM.v.html
  2. 28 0
      people.inf.ethz.ch/wirth/FPGA-relatedWork/Divider.v.html
  3. 28 0
      people.inf.ethz.ch/wirth/FPGA-relatedWork/Multiplier.v.html
  4. 28 0
      people.inf.ethz.ch/wirth/FPGA-relatedWork/Multiplier1.v.html
  5. 10 0
      people.inf.ethz.ch/wirth/FPGA-relatedWork/PROM.v.html
  6. 24 0
      people.inf.ethz.ch/wirth/FPGA-relatedWork/RISC0.ucf.html
  7. 180 0
      people.inf.ethz.ch/wirth/FPGA-relatedWork/RISC0.v.html
  8. 57 0
      people.inf.ethz.ch/wirth/FPGA-relatedWork/RISC0Top.v.html
  9. 34 0
      people.inf.ethz.ch/wirth/FPGA-relatedWork/RS232R.v.html
  10. 33 0
      people.inf.ethz.ch/wirth/FPGA-relatedWork/RS232T.v.html
  11. 4 0
      people.inf.ethz.ch/wirth/Lola/Sources/DCMX3.v.html
  12. 28 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/Divider.v.html
  13. 28 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/Divider0.v.html
  14. 132 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/FPAdder.v.html
  15. 45 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/FPDivider.v.html
  16. 34 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/FPMultiplier.v.html
  17. 22 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/LeftShifter.v.html
  18. 44 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/MouseP.v.html
  19. 28 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/MouseX.v.html
  20. 25 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/Multiplier.v.html
  21. 28 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/Multiplier1.v.html
  22. 12 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/PROM.v.html
  23. 33 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/PS2.v.html
  24. 121 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RISC5.ucf.html
  25. 184 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RISC5.v.html
  26. 146 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RISC5Top.v.html
  27. 147 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RISC5a.v.html
  28. 38 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RS232R.v.html
  29. 35 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RS232T.v.html
  30. 46 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/Registers.v.html
  31. 24 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RightShifter.v.html
  32. 36 0
      people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/SPI.v.html

+ 13 - 0
people.inf.ethz.ch/wirth/FPGA-relatedWork/DRAM.v.html

@@ -0,0 +1,13 @@
+`timescale 1ns / 1ps
+module DRAM(input [10:0] adr,
+    input [31:0] din,
+    output reg [31:0] dout,
+    input we,
+    input clk);
+reg [31:0] mem [2047: 0];
+always @(posedge clk) begin
+    if (we) mem[adr] <= din;
+	 dout <= mem[adr];
+end	 
+endmodule
+

+ 28 - 0
people.inf.ethz.ch/wirth/FPGA-relatedWork/Divider.v.html

@@ -0,0 +1,28 @@
+`timescale 1ns / 1ps  // NW 31.10.10
+
+module Divider(
+  input clk, run,
+  output stall,
+  input [31:0] x, y,
+  output [31:0] quot, rem);
+
+reg [4:0] S;  // state
+reg [31:0] r3, q2;
+wire [31:0] r0, r1, r2, q0, q1, d;
+
+assign stall = run & ~(S == 31);
+assign r0 = (S == 0) ? 0 : r3;
+assign d = r1 - y;
+assign r1 = {r0[30:0], q0[31]};
+assign r2 = d[31] ? r1 : d;
+assign q0 = (S == 0) ? x : q2;
+assign q1 = {q0[30:0], ~d[31]};
+assign rem = r2;
+assign quot = q1;
+
+always @ (posedge(clk)) begin
+  r3 <= r2; q2 <= q1;
+  S <= run ? S+1 : 0;
+end
+
+endmodule

+ 28 - 0
people.inf.ethz.ch/wirth/FPGA-relatedWork/Multiplier.v.html

@@ -0,0 +1,28 @@
+`timescale 1ns / 1ps  // NW 3.12.2010
+
+module Multiplier(
+  input clk, run, u,
+  output stall,
+  input [31:0] x, y,
+  output [63:0] z);
+
+reg [4:0] S;    // state
+reg [31:0] B2, A2;  // high and low parts of partial product
+wire [32:0] B0, B00, B01;
+wire [31:0] B1, A0, A1;
+
+assign stall = run & ~(S == 31);
+assign B00 = (S == 0) ? 0 : {B2[31] & u, B2};
+assign B01 = A0[0] ? {y[31] & u, y} : 0;
+assign B0 = ((S == 31) & u) ? B00 - B01 : B00 + B01;
+assign B1 = B0[32:1];
+assign A0 = (S == 0) ? x : A2;
+assign A1 = {B0[0], A0[31:1]};
+assign z = {B1, A1};
+
+always @ (posedge(clk)) begin
+  B2 <= B1; A2 <= A1;
+  S <= run ? S+1 : 0;
+end
+
+endmodule

+ 28 - 0
people.inf.ethz.ch/wirth/FPGA-relatedWork/Multiplier1.v.html

@@ -0,0 +1,28 @@
+`timescale 1ns / 1ps  // NW 29.4.2011
+module Multiplier1(
+  input clk, run, u,
+  output stall,
+  input [31:0] x, y,
+  output [63:0] z);
+	 
+reg S;  // state
+reg [15:0] z0;
+reg [47:0] z1, z2;
+wire [35:0] p0, p1, p2, p3;
+
+assign stall = run & ~S;
+assign z[15:0] = z0;
+assign z[63:16] = z1 + z2;
+
+MULT18X18 mult0(.P(p0), .A({2'b0, x[15:0]}), .B({2'b0, y[15:0]}));
+MULT18X18 mult1(.P(p1), .A({{2{u&x[31]}}, x[31:16]}), .B({2'b0, y[15:0]}));
+MULT18X18 mult2(.P(p2), .A({2'b0, x[15:0]}), .B({{2{u&y[31]}}, y[31:16]}));
+MULT18X18 mult3(.P(p3), .A({{2{u&x[31]}}, x[31:16]}), .B({{2{u&y[31]}}, y[31:16]}));
+
+always @(posedge clk) begin
+  S <= stall;
+  z0 <= p0[15:0];
+  z1 <= {{32'b0}, p0[31:16]} + {{16{u&p1[31]}}, p1[31:0]};
+  z2 <= {{16{u&p2[31]}}, p2[31:0]} + {p3[31:0], 16'b0};
+end
+endmodule

+ 10 - 0
people.inf.ethz.ch/wirth/FPGA-relatedWork/PROM.v.html

@@ -0,0 +1,10 @@
+`timescale 1ns / 1ps
+module PROM(
+    input [10:0] adr,
+    output reg [31:0] data,
+    input clk);
+reg [31:0] mem [2047: 0];
+initial $readmemh("../prom.mem", mem);
+always @(posedge clk) data <= mem[adr];
+endmodule
+

+ 24 - 0
people.inf.ethz.ch/wirth/FPGA-relatedWork/RISC0.ucf.html

@@ -0,0 +1,24 @@
+NET "CLK50M" LOC = "T9" ;
+NET "CLK50M" PERIOD = 20.0ns HIGH 50%;
+NET "rstIN" LOC = "L14";
+
+NET "TxD" LOC = "R13"; 
+NET "RxD" LOC = "T13" ; 
+
+NET "swi[0]" LOC = "F12";
+NET "swi[1]" LOC = "G12";
+NET "swi[2]" LOC = "H14";
+NET "swi[3]" LOC = "H13";
+NET "swi[4]" LOC = "J14";
+NET "swi[5]" LOC = "J13";
+NET "swi[6]" LOC = "K14";
+NET "swi[7]" LOC = "K13";
+
+NET "leds[0]" LOC = "K12";
+NET "leds[1]" LOC = "P14";
+NET "leds[2]" LOC = "L12";
+NET "leds[3]" LOC = "N14";
+NET "leds[4]" LOC = "P13";
+NET "leds[5]" LOC = "N12";
+NET "leds[6]" LOC = "P12";
+NET "leds[7]" LOC = "P11";

+ 180 - 0
people.inf.ethz.ch/wirth/FPGA-relatedWork/RISC0.v.html

@@ -0,0 +1,180 @@
+`timescale 1ns / 1ps  // NW 8.10.12  rev. 26.12.2013
+
+module RISC0(
+input clk, rst,
+input [31:0] inbus,
+output [5:0] ioadr,
+output iord, iowr,
+output [31:0] outbus);
+
+reg [11:0] PC;
+reg N, Z, C, OV;  // condition flags
+reg [31:0] R [0:15];  // array of 16 registers
+reg [31:0] H;  // aux register
+reg stall1;
+
+wire [31:0] IR;
+wire [31:0] pmout;
+wire [11:0] pcmux, nxpc;
+wire cond, S;
+wire sa, sb, sc;
+
+wire p, q, u, v, w;  // instruction fields
+wire [3:0] op, ira, ira0, irb, irc;
+wire [2:0] cc;
+wire [15:0] imm;
+wire [19:0] off;
+
+wire regwr;
+wire [13:0] dmadr;
+wire dmwr, ioenb;
+wire [31:0] dmin, dmout;
+wire [1:0] sc1, sc0;  // shift counts
+
+wire [31:0] A, B, C0, C1, regmux;
+wire [31:0] s1, s2, s3, t1, t2, t3;
+wire [32:0] aluRes;
+wire [31:0] quotient, remainder;
+wire [63:0] product;
+wire stall, stallL, stallM, stallD;
+
+wire MOV, LSL, ASR, ROR, AND, ANN, IOR, XOR;  // operation signals
+wire ADD, SUB, MUL, DIV; 
+wire LDR, STR, BR;
+
+PROM PM (.adr(pcmux[10:0]), .data(pmout), .clk(clk));
+DRAM DM (.adr(dmadr[12:2]), .din(dmin), .dout(dmout), .we(dmwr), .clk(clk));
+
+Multiplier1 mulUnit (.clk(clk), .run(MUL), .stall(stallM),
+   .u(~u), .x(B), .y(C1), .z(product));
+
+Divider divUnit (.clk(clk), .run(DIV), .stall(stallD),
+   .x(B), .y(C1), .quot(quotient), .rem(remainder));
+
+assign IR = pmout;  // decoding
+assign p = IR[31];
+assign q = IR[30];
+assign u = IR[29];
+assign v = IR[28];
+assign w = IR[16];
+assign cc  = IR[26:24];
+assign ira = IR[27:24];
+assign irb = IR[23:20];
+assign op  = IR[19:16];
+assign irc = IR[3:0];
+assign imm = IR[15:0];
+assign off = IR[19:0];
+
+assign MOV = ~p & (op == 0);
+assign LSL = ~p & (op == 1);
+assign ASR = ~p & (op == 2);
+assign ROR = ~p & (op == 3);
+assign AND = ~p & (op == 4);
+assign ANN = ~p & (op == 5);
+assign IOR = ~p & (op == 6);
+assign XOR = ~p & (op == 7);
+assign ADD = ~p & (op == 8);
+assign SUB = ~p & (op == 9);
+assign MUL = ~p & (op == 10);
+assign DIV = ~p & (op == 11);
+
+assign LDR = p & ~q & ~u;
+assign STR = p & ~q & u;
+assign BR  = p & q;
+
+assign A = R[ira0];  // register data signals
+assign B = R[irb];
+assign C0 = R[irc];
+
+// Arithmetic-logical unit (ALU)
+assign ira0 = BR ? 15 : ira;
+assign C1 = ~q ? C0 : {{16{v}}, imm};
+assign dmadr = B[13:0] + off[13:0];
+assign dmwr = STR & ~stall;
+assign dmin = A;
+
+assign ioenb = (dmadr[13:6] == 8'b11111111);
+assign iowr = STR & ioenb;
+assign iord = LDR & ioenb;
+assign ioadr = dmadr[5:0];
+assign outbus = A;
+
+assign sc0 = C1[1:0];
+assign sc1 = C1[3:2];
+
+// shifter for ASR and ROR
+assign s1 = (sc0 == 3) ? {(w ? B[2:0] : {3{B[31]}}), B[31:3]} :
+    (sc0 == 2) ? {(w ? B[1:0] : {2{B[31]}}), B[31:2]} :
+    (sc0 == 1) ? {(w ? B[0] : B[31]), B[31:1]} : B;
+assign s2 = (sc1 == 3) ? {(w ? s1[11:0] : {12{s1[31]}}), s1[31:12]} :
+    (sc1 == 2) ? {(w ? s1[7:0] : {8{s1[31]}}), s1[31:8]} :
+    (sc1 == 1) ? {(w ? s1[3:0] : {4{s1[31]}}), s1[31:4]} : s1;
+assign s3 = C1[4] ? {(w ? s2[15:0] : {16{s2[31]}}), s2[31:16]} : s2;
+
+// shifter for LSL
+assign t1 = (sc0 == 3) ? {B[28:0], 3'b0} :
+    (sc0 == 2) ? {B[29:0], 2'b0} :
+    (sc0 == 1) ? {B[30:0], 1'b0} : B;
+assign t2 = (sc1 == 3) ? {t1[19:0], 12'b0} :
+    (sc1 == 2) ? {t1[23:0], 8'b0} :
+    (sc1 == 1) ? {t1[27:0], 4'b0} : t1;
+assign t3 = C1[4] ? {t2[15:0], 16'b0} : t2;
+
+assign aluRes =
+  MOV ? (q ?
+    (~u ? {{16{v}}, imm} : {imm, 16'b0}) :
+    (~u ? C0 : (~v ? H : {N, Z, C, OV, 20'b0, 8'b10100000}))) :
+  LSL ? t3 :
+  (ASR|ROR) ? s3 :
+  AND ? B & C1 :
+  ANN ? B & ~C1 :
+  IOR  ? B | C1 :
+  XOR ? B ^ C1 :
+  ADD ? B + C1 + (u & C) :
+  SUB ? B - C1 - (u & C) :
+  MUL ? product[31:0] :
+  DIV ? quotient : 0;
+
+assign regwr = ~p & ~stall | (LDR & stall1)| (BR & cond & v) ;
+assign regmux = 
+  (LDR & ~ioenb) ? dmout :
+  (LDR & ioenb) ? inbus :
+  (BR & v) ? {18'b0, nxpc, 2'b0} : aluRes;
+
+// Control unit CU
+assign S = N ^ OV;
+assign nxpc = PC + 1;
+assign cond = IR[27] ^
+  ((cc == 0) & N | // MI, PL
+   (cc == 1) & Z | // EQ, NE
+   (cc == 2) & C | // CS, CC
+   (cc == 3) & OV | // VS, VC
+   (cc == 4) & (C|Z) | // LS, HI
+   (cc == 5) & S | // LT, GE
+   (cc == 6) & (S|Z) | // LE, GT
+   (cc == 7)); // T, F
+
+assign pcmux =
+  (~rst) ? 0 :
+  (stall) ? PC :
+  (BR & cond & u) ? off[11:0] + nxpc :
+  (BR & cond & ~u) ? C0[13:2] : nxpc;
+
+assign sa = aluRes[31];
+assign sb = B[31];
+assign sc = C1[31] ^ SUB;
+
+assign stall = stallL | stallM | stallD;
+assign stallL = LDR & ~stall1;
+
+always @ (posedge clk) begin
+  PC <= pcmux;
+  stall1 <= stallL;
+  R[ira0] <= regwr ? regmux : A;
+  N <= regwr ? regmux[31] : N;
+  Z <= regwr ? (regmux[31:0] == 0) : Z;
+  C <= (ADD|SUB) ? aluRes[32] : C;
+  OV <= (ADD|SUB) ? (sa & ~sb & ~sc | ~sa & sb & sc) : OV;
+  H <= MUL ? product[63:32] : DIV ? remainder : H;
+end 
+endmodule 

+ 57 - 0
people.inf.ethz.ch/wirth/FPGA-relatedWork/RISC0Top.v.html

@@ -0,0 +1,57 @@
+`timescale 1ns / 1ps  // NW 27.5.09  LL 10.12.09  NW 28.7.2011
+
+module RISC0Top(
+  input CLK50M,
+  input rstIn,
+  input RxD,
+  input [7:0] swi,
+  output TxD,
+  output [7:0] leds);
+	 
+wire clk, clk50;
+reg rst, clk25;
+
+wire[5:0] ioadr;
+wire [3:0] iowadr;
+wire iowr;
+wire[31:0] inbus, outbus;
+
+wire [7:0] dataTx, dataRx;
+wire rdyRx, doneRx, startTx, rdyTx;
+wire limit;  // of cnt0
+
+reg [7:0] Lreg;
+reg [15:0] cnt0;
+reg [31:0] cnt1; // milliseconds
+
+RISC0 riscx(.clk(clk), .rst(rst), .iord(iord), .iowr(iowr),
+   .ioadr(ioadr), .inbus(inbus), .outbus(outbus));
+			
+RS232R receiver(.clk(clk), .rst(rst), .RxD(RxD), .done(doneRx), .data(dataRx), .rdy(rdyRx));
+RS232T transmitter(.clk(clk), .rst(rst), .start(startTx), .data(dataTx), .TxD(TxD), .rdy(rdyTx));
+
+assign iowadr = ioadr[5:2];
+assign inbus = (iowadr == 0) ? cnt1 :
+    (iowadr == 1) ? swi :
+    (iowadr == 2) ? {24'b0, dataRx} :
+    (iowadr == 3) ? {30'b0, rdyTx, rdyRx} : 0;
+    
+assign dataTx = outbus[7:0];
+assign startTx = iowr & (iowadr == 2);
+assign doneRx = iord & (iowadr == 2);
+assign limit = (cnt0 == 25000);
+assign leds = Lreg;
+
+always @(posedge clk) 
+begin
+  rst <= ~rstIn;
+  Lreg <= ~rst ? 0 : (iowr & (iowadr == 1)) ? outbus[7:0] : Lreg;
+  cnt0 <= limit ? 0 : cnt0 + 1;
+  cnt1 <= limit ? cnt1 + 1 : cnt1;
+end
+
+//The Clocks
+IBUFG clkInBuf(.I(CLK50M), .O(clk50));
+always @ (posedge clk50) clk25 <= ~clk25;
+BUFG clk150buf(.I(clk25), .O(clk));
+endmodule

+ 34 - 0
people.inf.ethz.ch/wirth/FPGA-relatedWork/RS232R.v.html

@@ -0,0 +1,34 @@
+`timescale 1ns / 1ps  // NW 4.5.09 / 15.8.10 / 15.11.10
+
+// RS232 receiver for 19200 bps, 8 bit data
+// clock is 25 MHz; 25000 / 1302 = 19.2 KHz
+// clock is 35 MHz; 35000 / 1823 = 19.2 KHz
+
+module RS232R(
+    input clk, rst,
+    input done,   // "byte has been read"
+    input RxD,
+    output rdy,
+    output [7:0] data);
+
+wire endtick, midtick;
+reg run, stat;
+reg [11:0] tick;
+reg [3:0] bitcnt;
+reg [7:0] shreg;
+
+assign endtick = tick == 1302;
+assign midtick = tick == 651;
+assign endbit = bitcnt == 8;
+assign data = shreg;
+assign rdy = stat;
+
+always @ (posedge clk) begin
+  run <= (~RxD) ? 1 : (~rst | endtick & endbit) ? 0 : run;
+  tick <= (run & ~endtick) ? tick + 1 : 0;
+  bitcnt <= (endtick & ~endbit) ? bitcnt + 1 :
+    (endtick & endbit) ? 0 : bitcnt;
+  shreg <= midtick ? {RxD, shreg[7:1]} : shreg;
+  stat <= (endtick & endbit) ? 1 : (~rst | done) ? 0 : stat;
+end	 
+endmodule

+ 33 - 0
people.inf.ethz.ch/wirth/FPGA-relatedWork/RS232T.v.html

@@ -0,0 +1,33 @@
+`timescale 1ns / 1ps  // NW 4.5.09 / 15.8.10 / 15.11.10
+
+// RS232 receiver for 19200 bps, 8 bit data
+// clock is 25 MHz; 25000 / 1302 = 19.2 KHz
+// clock is 35 MHz; 35000 / 1823 = 19.2 KHz
+
+module RS232T(
+    input clk, rst,
+    input start, // request to accept and send a byte
+    input [7:0] data,
+    output rdy,
+    output TxD);
+
+wire endtick, endbit;
+reg run;
+reg [11:0] tick;
+reg [3:0] bitcnt;
+reg [8:0] shreg;
+
+assign endtick = tick == 1302;
+assign endbit = bitcnt == 9;
+assign rdy = ~run;
+assign TxD = shreg[0];
+
+always @ (posedge clk) begin
+  run <= (~rst | endtick & endbit) ? 0 : start ? 1 : run;
+  tick <= (run & ~endtick) ? tick + 1 : 0;
+  bitcnt <= (endtick & ~endbit) ? bitcnt + 1 :
+    (endtick & endbit) ? 0 : bitcnt;
+  shreg <= (~rst) ? 1 : start ? {data, 1'b0} :
+    endtick ? {1'b1, shreg[8:1]} : shreg;
+end
+endmodule

+ 4 - 0
people.inf.ethz.ch/wirth/Lola/Sources/DCMX3.v.html

@@ -0,0 +1,4 @@
+module DCMX3 (input CLKIN, output CLKFX);
+(* LOC = "DCM_X1Y1" *) DCM #(.CLKFX_MULTIPLY(3), .CLK_FEEDBACK("NONE"))
+  dcm(.CLKIN(CLKIN), .CLKFX(CLKFX));
+endmodule

+ 28 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/Divider.v.html

@@ -0,0 +1,28 @@
+`timescale 1ns / 1ps  // NW 20.9.2015
+
+module Divider(
+  input clk, run, u,
+  output stall,
+  input [31:0] x, y,  // y > 0
+  output [31:0] quot, rem);
+
+reg [5:0] S;  // state
+reg [63:0] RQ;
+wire sign;
+wire [31:0] x0, w0, w1;
+
+assign stall = run & ~(S == 33);
+assign sign = x[31] & u;
+assign x0 = sign ? -x : x;
+assign w0 = RQ[62: 31];
+assign w1 = w0 - y;
+assign quot = ~sign ? RQ[31:0] :
+  (RQ[63:32] == 0) ? -RQ[31:0] : -RQ[31:0] - 1;
+assign rem = ~sign ? RQ[63:32] :
+  (RQ[63:32] == 0) ? 0 : y - RQ[63:32];
+
+always @ (posedge(clk)) begin
+  RQ <= (S == 0) ? {32'b0, x0} : {(w1[31] ? w0 : w1), RQ[30:0], ~w1[31]};
+  S <= run ? S+1 : 0;
+end
+endmodule

+ 28 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/Divider0.v.html

@@ -0,0 +1,28 @@
+`timescale 1ns / 1ps  // NW 31.10.10
+
+module Divider(
+  input clk, run,
+  output stall,
+  input [31:0] x, y,  // x >= 0, y > 0
+  output [31:0] quot, rem);
+
+reg [4:0] S;  // state
+reg [31:0] R, Q;
+wire [31:0] r0, r1, r2, q0, q1, d;
+
+assign stall = run & ~(S == 31);
+assign r0 = (S == 0) ? 0 : R;
+assign d = r1 - y;
+assign r1 = {r0[30:0], q0[31]};
+assign r2 = d[31] ? r1 : d;
+assign q0 = (S == 0) ? x : Q;
+assign q1 = {q0[30:0], ~d[31]};
+assign rem = r2;
+assign quot = q1;
+
+always @ (posedge(clk)) begin
+  R <= r2; Q <= q1;
+  S <= run ? S+1 : 0;
+end
+
+endmodule

+ 132 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/FPAdder.v.html

@@ -0,0 +1,132 @@
+`timescale 1ns / 1ps  // NW 4.10.2016  pipelined
+// u = 1: FLT; v = 1: FLOOR
+
+module FPAdder(
+  input clk, run, u, v,
+  input [31:0] x, y,
+  output stall,
+  output [31:0] z);
+
+reg [1:0] State;
+
+wire xs, ys, xn, yn;  // signs, null
+wire [7:0] xe, ye;
+wire [24:0] xm, ym;
+
+wire [8:0] dx, dy, e0, e1;
+wire [7:0] sx, sy;  // shift counts
+wire [1:0] sx0, sx1, sy0, sy1;
+wire sxh, syh;
+wire [24:0] x0, x1, x2, y0, y1, y2;
+reg [24:0] x3, y3;
+
+reg [26:0] Sum;
+wire [26:0] s;
+
+wire z24, z22, z20, z18, z16, z14, z12, z10, z8, z6, z4, z2;
+wire [4:0] sc;  // shift count
+wire [1:0] sc0, sc1;
+wire [24:0] t1, t2;
+reg [24:0] t3;
+
+assign xs = x[31];  // sign x
+assign xe = u ? 8'h96 : x[30:23];  // expo x
+assign xm = {~u|x[23], x[22:0], 1'b0};  //mant x
+assign xn = (x[30:0] == 0);
+assign ys = y[31];  // sign y
+assign ye = y[30:23];  // expo y
+assign ym = {~u&~v, y[22:0], 1'b0};  //mant y
+assign yn = (y[30:0] == 0);
+
+assign dx = xe - ye;
+assign dy = ye - xe;
+assign e0 = (dx[8]) ? ye : xe;
+assign sx = dy[8] ? 0 : dy;
+assign sy = dx[8] ? 0 : dx;
+assign sx0 = sx[1:0];
+assign sx1 = sx[3:2];
+assign sy0 = sy[1:0];
+assign sy1 = sy[3:2];
+assign sxh = sx[7] | sx[6] | sx[5];
+assign syh = sy[7] | sy[6] | sy[5];
+
+// denormalize, shift right
+assign x0 = xs&~u ? -xm : xm;
+assign x1 = (sx0 == 3) ? {{3{xs}}, x0[24:3]} :
+  (sx0 == 2) ? {{2{xs}}, x0[24:2]} : (sx0 == 1) ? {xs, x0[24:1]} : x0;
+assign x2 = (sx1 == 3) ? {{12{xs}}, x1[24:12]} :
+  (sx1 == 2) ? {{8{xs}}, x1[24:8]} : (sx1 == 1) ? {{4{xs}}, x1[24:4]} : x1;
+always @ (posedge(clk))
+  x3 <= sxh ? {25{xs}} : (sx[4] ? {{16{xs}}, x2[24:16]} : x2);
+
+assign y0 = ys&~u ? -ym : ym;
+assign y1 = (sy0 == 3) ? {{3{ys}}, y0[24:3]} :
+  (sy0 == 2) ? {{2{ys}}, y0[24:2]} : (sy0 == 1) ? {ys, y0[24:1]} : y0;
+assign y2 = (sy1 == 3) ? {{12{ys}}, y1[24:12]} :
+  (sy1 == 2) ? {{8{ys}}, y1[24:8]} : (sy1 == 1) ? {{4{ys}}, y1[24:4]} : y1;
+always @ (posedge(clk))
+	y3 <= syh ? {25{ys}} : (sy[4] ? {{16{ys}}, y2[24:16]} : y2);
+	
+// add
+always @ (posedge(clk)) Sum <= {xs, xs, x3} + {ys, ys, y3};
+assign s = (Sum[26] ? -Sum : Sum) + 1;
+
+// post-normalize
+assign z24 = ~s[25] & ~ s[24];
+assign z22 = z24 & ~s[23] & ~s[22];
+assign z20 = z22 & ~s[21] & ~s[20];
+assign z18 = z20 & ~s[19] & ~s[18];
+assign z16 = z18 & ~s[17] & ~s[16];
+assign z14 = z16 & ~s[15] & ~s[14];
+assign z12 = z14 & ~s[13] & ~s[12];
+assign z10 = z12 & ~s[11] & ~s[10];
+assign z8 = z10 & ~s[9] & ~s[8];
+assign z6 = z8 & ~s[7] & ~s[6];
+assign z4 = z6 & ~s[5] & ~s[4];
+assign z2 = z4 & ~s[3] & ~s[2];
+
+assign sc[4] = z10;  // sc = shift count of post normalization
+assign sc[3] = z18 & (s[17] | s[16] | s[15] | s[14] | s[13] | s[12] | s[11] | s[10])
+      | z2;
+assign sc[2] = z22 & (s[21] | s[20] | s[19] | s[18])
+      | z14 & (s[13] | s[12] | s[11] | s[10])
+      | z6 & (s[5] | s[4] | s[3] | s[2]);
+assign sc[1] = z24 & (s[23] | s[22])
+      | z20 & (s[19] | s[18])
+      | z16 & (s[15] | s[14])
+      | z12 & (s[11] | s[10])
+      | z8 & (s[7] | s[6])
+      | z4 & (s[3] | s[2]);
+assign sc[0] = ~s[25] & s[24]
+      | z24 & ~s[23] & s[22]
+      | z22 & ~s[21] & s[20]
+      | z20 & ~s[19] & s[18]
+      | z18 & ~s[17] & s[16]
+      | z16 & ~s[15] & s[14]
+      | z14 & ~s[13] & s[12]
+      | z12 & ~s[11] & s[10]
+      | z10 & ~s[9] & s[8]
+      | z8 & ~s[7] & s[6]
+      | z6 & ~s[5] & s[4]
+      | z4 & ~s[3] & s[2];
+
+assign e1 = e0 - sc + 1;
+assign sc0 = sc[1:0];
+assign sc1 = sc[3:2];
+
+assign t1 = (sc0 == 3) ? {s[22:1], 3'b0} :
+  (sc0 == 2) ? {s[23:1], 2'b0} : (sc0 == 1) ? {s[24:1], 1'b0} : s[25:1];
+assign t2 = (sc1 == 3) ? {t1[12:0], 12'b0} :
+  (sc1 == 2) ? {t1[16:0], 8'b0} : (sc1 == 1) ? {t1[20:0], 4'b0} : t1;
+always @ (posedge(clk)) t3 <= sc[4] ? {t2[8:0], 16'b0} : t2;
+
+assign stall = run & ~(State == 3);
+always @ (posedge(clk)) State <= run ? State + 1 : 0;
+
+assign z = v ? {{7{Sum[26]}}, Sum[25:1]} :  // FLOOR
+    xn ? (u|yn ? 0 : y) :   // FLT or x = y = 0
+    yn ? x :
+    ((t3 == 0) | e1[8]) ? 0 : 
+	 {Sum[26], e1[7:0], t3[23:1]};
+endmodule
+

+ 45 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/FPDivider.v.html

@@ -0,0 +1,45 @@
+`timescale 1ns / 1ps   // NW 16.9.2016
+
+module FPDivider(
+    input clk, run,
+    input [31:0] x,
+    input [31:0] y,
+    output stall,
+    output [31:0] z);
+
+reg [4:0] S;  // state
+reg [23:0] R;
+reg [25:0] Q;
+
+wire sign;
+wire [7:0] xe, ye;
+wire [8:0] e0, e1;
+wire [24:0] r0, r1, d;
+wire [25:0] q0;
+wire [24:0] z0, z1;
+
+assign sign = x[31]^y[31];
+assign xe = x[30:23];
+assign ye = y[30:23];
+assign e0 = {1'b0, xe} - {1'b0, ye};
+assign e1 = e0 + 126 + Q[25];
+assign stall = run & ~(S == 26);
+
+assign r0 = (S == 0) ? {2'b01, x[22:0]} : {R, 1'b0};
+assign r1 = d[24] ? r0 : d;
+assign d = r0 - {2'b01, y[22:0]};
+assign q0 = (S == 0) ? 0 : Q;
+
+assign z0 = Q[25] ? Q[25:1] : Q[24:0];
+assign z1 = z0 + 1;
+assign z = (xe == 0) ? 0 :
+  (ye == 0) ? {sign, 8'b11111111, 23'b0} :  // div by 0
+  (~e1[8]) ? {sign, e1[7:0], z1[23:1]} :
+  (~e1[7]) ? {sign, 8'b11111111, z0[23:1]} : 0;  // NaN
+
+always @ (posedge(clk)) begin
+  R <= r1[23:0];
+  Q <= {q0[24:0], ~d[24]};
+  S <= run ? S+1 : 0;
+end
+endmodule

+ 34 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/FPMultiplier.v.html

@@ -0,0 +1,34 @@
+`timescale 1ns / 1ps  // NW 15.9.2015  8.8.2016
+module FPMultiplier(
+  input clk, run,
+  input [31:0] x, y,
+  output stall,
+  output [31:0] z);
+
+reg [4:0] S;  // state
+reg [47:0] P; // product
+
+wire sign;
+wire [7:0] xe, ye;
+wire [8:0] e0, e1;
+wire [24:0] w1, z0;
+wire [23:0] w0;
+
+assign sign = x[31] ^ y[31];
+assign xe = x[30:23];
+assign ye = y[30:23];
+assign e0 = xe + ye;
+assign e1 = e0 - 127 + P[47];
+
+assign stall = run & ~(S == 25);
+assign w0 = P[0] ? {1'b1, y[22:0]} : 0;
+assign w1 = {1'b0, P[47:24]} + {1'b0, w0};
+assign z0 = P[47] ? P[47:23]+1 : P[46:22]+1;  // round and normalize
+assign z = (xe == 0) | (ye == 0) ? 0 :
+   (~e1[8]) ? {sign, e1[7:0], z0[23:1]} :
+   (~e1[7]) ? {sign, 8'b11111111, z0[23:1]} : 0;
+always @ (posedge(clk)) begin
+    P <= (S == 0) ? {24'b0, 1'b1, x[22:0]} : {w1, P[23:1]};
+    S <= run ? S+1 : 0;
+end
+endmodule

+ 22 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/LeftShifter.v.html

@@ -0,0 +1,22 @@
+`timescale 1ns / 1ps  // NW 9.11.2016
+
+module LeftShifter(
+input [31:0] x,
+input [4:0] sc,
+output [31:0] y);
+
+// shifter for LSL
+wire [1:0] sc0, sc1;
+wire [31:0] t1, t2;
+
+assign sc0 = sc[1:0];
+assign sc1 = sc[3:2];
+
+assign t1 = (sc0 == 3) ? {x[28:0], 3'b0} :
+    (sc0 == 2) ? {x[29:0], 2'b0} :
+    (sc0 == 1) ? {x[30:0], 1'b0} : x;
+assign t2 = (sc1 == 3) ? {t1[19:0], 12'b0} :
+    (sc1 == 2) ? {t1[23:0], 8'b0} :
+    (sc1 == 1) ? {t1[27:0], 4'b0} : t1;
+assign y = sc[4] ? {t2[15:0], 16'b0} : t2;
+endmodule

+ 44 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/MouseP.v.html

@@ -0,0 +1,44 @@
+`timescale 1ns / 1ps  // PS/2 Logitech mouse PDR 14.10.2013 / 8.9.2015
+module MouseP(
+  input clk, rst,
+  inout msclk, msdat,
+  output [27:0] out);
+
+  reg [9:0] x, y;
+  reg [2:0] btns;
+  reg Q0, Q1, run;
+  reg [31:0] shreg;
+  wire shift, endbit, reply;
+  wire [9:0] dx, dy;
+
+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1                 bit
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// ===============================================================
+// p y y y y y y y y 0 1 p x x x x x x x x 0 1 p Y X t s 1 M R L 0 normal
+// ---------------------------------------------------------------
+// p ----response--- 0 1 --InitBuf echoed--- 1 1 1 1 1 1 1 1 1 1 1 init
+// ---------------------------------------------------------------
+// p = parity (ignored); X, Y = overflow; s, t = x, y sign bits
+
+  // initially need to send F4 cmd (start reporting); add start and parity bits
+  localparam InitBuf = 32'b11111111111111111111110_11110100_0;
+  assign msclk = ~rst ? 0 : 1'bz;  // initial drive clock low
+  assign msdat = ~run & ~shreg[0] ? 0 : 1'bz;
+  assign shift = Q1 & ~Q0;  // falling edge detector
+  assign reply = ~run & ~shreg[11];  // start bit of echoed InitBuf, if response
+  assign endbit = run & ~shreg[0];  // normal packet received
+  assign dx = {{2{shreg[5]}}, shreg[7] ? 8'b0 : shreg[19:12]};  //sign+overfl
+  assign dy = {{2{shreg[6]}}, shreg[8] ? 8'b0 : shreg[30:23]};  //sign+overfl
+  assign out = {run, btns, 2'b0, y, 2'b0, x};
+
+  always @ (posedge clk) begin
+    run <= rst & (reply | run); Q0 <= msclk; Q1 <= Q0;
+    shreg <= ~rst ? InitBuf : (endbit | reply) ? -1 : shift ? {msdat,
+shreg[31:1]} : shreg;
+    x <= ~rst ? 0 : endbit ? x + dx : x;  y <= ~rst ? 0 : endbit ? y + dy
+: y;
+    btns <= ~rst ? 0 : endbit ? {shreg[1], shreg[3], shreg[2]} : btns;
+  end
+
+endmodule
+

+ 28 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/MouseX.v.html

@@ -0,0 +1,28 @@
+`timescale 1ns / 1ps
+// N.Wirth  10.10.2012
+module MouseX(
+  input clk,
+  input [6:0] in,
+  output [27:0] out);
+
+  reg x00, x01, x10, x11, y00, y01, y10, y11;
+  reg ML, MM, MR;  // keys
+  reg [9:0] x, y;  // counters
+
+  wire xup, xdn, yup, ydn;
+
+  assign xup = ~x00&~x01&~x10&x11 | ~x00&x01&x10&x11 | x00&~x01&~x10&~x11 | x00&x01&x10&~x11;
+  assign yup = ~y00&~y01&~y10&y11 | ~y00&y01&y10&y11 | y00&~y01&~y10&~y11 | y00&y01&y10&~y11;
+  assign xdn = ~x00&~x01&x10&~x11 | ~x00&x01&~x10&~x11 | x00&~x01&x10&x11 | x00&x01&~x10&x11;
+  assign ydn = ~y00&~y01&y10&~y11 | ~y00&y01&~y10&~y11 | y00&~y01&y10&y11 | y00&y01&~y10&y11;
+  assign out = {1'b0, ML, MM, MR, 2'b0, y, 2'b0, x};
+  
+  always @ (posedge clk) begin
+    x00 <= in[3]; x01 <= x00; x10 <= in[2]; x11 <= x10;
+    y00 <= in[1]; y01 <= y00; y10 <= in[0]; y11 <= y10;
+    MR <= ~in[4]; MM <= ~in[5]; ML <= ~in[6];
+    x <= xup ? x+1 : xdn ? x-1 : x; 
+    y <= yup ? y+1 : ydn ? y-1 : y;
+  end
+endmodule
+

+ 25 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/Multiplier.v.html

@@ -0,0 +1,25 @@
+`timescale 1ns / 1ps   // NW 14.9.2015
+
+module Multiplier(
+  input clk, run, u,
+  output stall,
+  input [31:0] x, y,
+  output [63:0] z);
+
+reg [5:0] S;    // state
+reg [63:0] P;   // product
+wire [31:0] w0;
+wire [32:0] w1;
+
+assign stall = run & ~(S == 33);
+assign w0 = P[0] ? y : 0;
+assign w1 = (S == 32) & u ? {P[63], P[63:32]} - {w0[31], w0} :
+       {P[63], P[63:32]} + {w0[31], w0};
+assign z = P;
+
+always @ (posedge(clk)) begin
+  P <= (S == 0) ? {32'b0, x} : {w1[32:0], P[31:1]};
+  S <= run ? S+1 : 0;
+end
+
+endmodule

+ 28 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/Multiplier1.v.html

@@ -0,0 +1,28 @@
+`timescale 1ns / 1ps  // NW 29.4.2011
+module Multiplier1(
+  input clk, run, u,
+  output stall,
+  input [31:0] x, y,
+  output [63:0] z);
+	 
+reg S;  // state
+reg [15:0] z0;
+reg [47:0] z1, z2;
+wire [35:0] p0, p1, p2, p3;
+
+assign stall = run & ~S;
+assign z[15:0] = z0;
+assign z[63:16] = z1 + z2;
+
+MULT18X18 mult0(.P(p0), .A({2'b0, x[15:0]}), .B({2'b0, y[15:0]}));
+MULT18X18 mult1(.P(p1), .A({{2{u&x[31]}}, x[31:16]}), .B({2'b0, y[15:0]}));
+MULT18X18 mult2(.P(p2), .A({2'b0, x[15:0]}), .B({{2{u&y[31]}}, y[31:16]}));
+MULT18X18 mult3(.P(p3), .A({{2{u&x[31]}}, x[31:16]}), .B({{2{u&y[31]}}, y[31:16]}));
+
+always @(posedge clk) begin
+  S <= stall;
+  z0 <= p0[15:0];
+  z1 <= {{32'b0}, p0[31:16]} + {{16{u&p1[31]}}, p1[31:0]};
+  z2 <= {{16{u&p2[31]}}, p2[31:0]} + {p3[31:0], 16'b0};
+end
+endmodule

+ 12 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/PROM.v.html

@@ -0,0 +1,12 @@
+`timescale 1ns / 1ps // 32-bit PROM initialised from hex file  PDR 23.12.13
+
+module PROM (input clk,
+  input [8:0] adr,
+  output reg [31:0] data);
+  
+reg [31:0] mem [511: 0];
+initial $readmemh("../prom.mem", mem);
+always @(posedge clk) data <= mem[adr];
+
+endmodule
+

+ 33 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/PS2.v.html

@@ -0,0 +1,33 @@
+`timescale 1ns / 1ps  // NW 20.10.2012
+// PS2 receiver for keyboard, 8 bit data
+// clock is 25 MHz; 25000 / 1302 = 19.2 KHz
+
+module PS2(
+    input clk, rst,
+    input done,   // "byte has been read"
+    output rdy,   // "byte is available"
+    output shift, // shift in, tramsmitter
+    output [7:0] data,
+    input PS2C,   // serial input
+    input PS2D);
+	 
+reg Q0, Q1;  // synchronizer and falling edge detector
+reg [10:0] shreg;
+reg [3:0] inptr, outptr;
+reg [7:0] fifo [15:0];  // 16 byte buffer
+wire endbit;
+
+assign endbit = ~shreg[0];  //start bit reached correct pos
+assign shift = Q1 & ~Q0;
+assign data = fifo[outptr];
+assign rdy = ~(inptr == outptr);
+
+always @ (posedge clk) begin
+  Q0 <= PS2C; Q1 <= Q0;
+  shreg <= (~rst | endbit) ? 11'h7FF :
+    shift ? {PS2D, shreg[10:1]} : shreg;
+  outptr <= ~rst ? 0 : rdy & done ? outptr+1 : outptr;
+  inptr <= ~rst ? 0 : endbit ? inptr+1 : inptr;
+  if (endbit) fifo[inptr] <= shreg[8:1];
+end	 
+endmodule

+ 121 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RISC5.ucf.html

@@ -0,0 +1,121 @@
+NET "CLK50M" LOC = "T9" ;
+
+NET "TxD" LOC = "R13";
+NET "RxD" LOC = "T13";
+
+NET "btn[0]" LOC = "M13";
+NET "btn[1]" LOC = "M14";
+NET "btn[2]" LOC = "L13";
+NET "btn[3]" LOC = "L14";
+
+NET "swi[0]" LOC = "F12";
+NET "swi[1]" LOC = "G12";
+NET "swi[2]" LOC = "H14";
+NET "swi[3]" LOC = "H13";
+NET "swi[4]" LOC = "J14";
+NET "swi[5]" LOC = "J13";
+NET "swi[6]" LOC = "K14";
+NET "swi[7]" LOC = "K13";
+
+NET "leds[0]" LOC = "K12";
+NET "leds[1]" LOC = "P14";
+NET "leds[2]" LOC = "L12";
+NET "leds[3]" LOC = "N14";
+NET "leds[4]" LOC = "P13";
+NET "leds[5]" LOC = "N12";
+NET "leds[6]" LOC = "P12";
+NET "leds[7]" LOC = "P11";
+
+# SRAM
+NET "SRce0" LOC = "P7";
+NET "SRce1" LOC = "N5";
+NET "SRwe" LOC = "G3";
+NET "SRoe" LOC = "K4";
+NET "SRbe[0]" LOC = "P6";
+NET "SRbe[1]" LOC = "T4";
+NET "SRbe[2]" LOC = "P5";
+NET "SRbe[3]" LOC = "R4";
+NET "SRadr[0]" LOC = "L5";
+NET "SRadr[1]" LOC = "N3";
+NET "SRadr[2]" LOC = "M4";
+NET "SRadr[3]" LOC = "M3";
+NET "SRadr[4]" LOC = "L4";
+NET "SRadr[5]" LOC = "G4";
+NET "SRadr[6]" LOC = "F3";
+NET "SRadr[7]" LOC = "F4";
+NET "SRadr[8]" LOC = "E3";
+NET "SRadr[9]" LOC = "E4";
+NET "SRadr[10]" LOC = "G5";
+NET "SRadr[11]" LOC = "H3";
+NET "SRadr[12]" LOC = "H4";
+NET "SRadr[13]" LOC = "J4";
+NET "SRadr[14]" LOC = "J3";
+NET "SRadr[15]" LOC = "K3";
+NET "SRadr[16]" LOC = "K5";
+NET "SRadr[17]" LOC = "L3";
+NET "SRdat[0]" LOC = "N7";
+NET "SRdat[1]" LOC = "T8";
+NET "SRdat[2]" LOC = "R6";
+NET "SRdat[3]" LOC = "T5";
+NET "SRdat[4]" LOC = "R5";
+NET "SRdat[5]" LOC = "C2";
+NET "SRdat[6]" LOC = "C1";
+NET "SRdat[7]" LOC = "B1";
+NET "SRdat[8]" LOC = "D3";
+NET "SRdat[9]" LOC = "P8";
+NET "SRdat[10]" LOC = "F2";
+NET "SRdat[11]" LOC = "H1";
+NET "SRdat[12]" LOC = "J2";
+NET "SRdat[13]" LOC = "L2";
+NET "SRdat[14]" LOC = "P1";
+NET "SRdat[15]" LOC = "R1";
+NET "SRdat[16]" LOC = "P2";
+NET "SRdat[17]" LOC = "N2";
+NET "SRdat[18]" LOC = "M2";
+NET "SRdat[19]" LOC = "K1";
+NET "SRdat[20]" LOC = "J1";
+NET "SRdat[21]" LOC = "G2";
+NET "SRdat[22]" LOC = "E1";
+NET "SRdat[23]" LOC = "D1";
+NET "SRdat[24]" LOC = "D2";
+NET "SRdat[25]" LOC = "E2";
+NET "SRdat[26]" LOC = "G1";
+NET "SRdat[27]" LOC = "F5";
+NET "SRdat[28]" LOC = "C3";
+NET "SRdat[29]" LOC = "K2";
+NET "SRdat[30]" LOC = "M1";
+NET "SRdat[31]" LOC = "N1";
+
+# VGA port
+NET "Hsync"  LOC = "R9";
+NET "Vsync"  LOC = "T10";
+NET "RGB[0]" LOC = "R11";
+NET "RGB[1]" LOC = "T12";
+NET "RGB[2]" LOC = "R12";
+
+# keyboard
+NET "PS2C" LOC = "M16" |PULLUP;
+NET "PS2D" LOC = "M15" |PULLUP;
+
+# PS/2 mouse and SPI (SD-Card and Network) on A2 connector
+NET "msclk" LOC = "E6" |PULLUP;  # pin 4
+NET "msdat" LOC = "C5" |PULLUP;  # pin 6
+NET "MOSI[0]" LOC = "D6";  # pin 7
+NET "MOSI[1]" LOC = "B11";  # pin 29
+NET "SCLK[0]" LOC = "D8";  # pin 13
+NET "SCLK[1]" LOC = "B12";  # pin 30
+NET "SS[0]" LOC = "D5";  # pin 5
+NET "SS[1]" LOC = "A12";  # pin 31
+NET "MISO[0]" LOC = "B4" |PULLUP;  # pin 17
+NET "MISO[1]" LOC = "A10" |PULLUP;  # pin 28
+NET "NEN" LOC = "B13";  # pin 32
+
+# general-purpose I/O port
+NET "gpio[0]" LOC = "C10";
+NET "gpio[1]" LOC = "E10";
+NET "gpio[2]" LOC = "C11";
+NET "gpio[3]" LOC = "D11";
+NET "gpio[4]" LOC = "C12";
+NET "gpio[5]" LOC = "D12";
+NET "gpio[6]" LOC = "E11";
+NET "gpio[7]" LOC = "B16";

+ 184 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RISC5.v.html

@@ -0,0 +1,184 @@
+`timescale 1ns / 1ps  // 31.8.2018
+//with interrupt and floating-point
+
+module RISC5(
+input clk, rst, irq, stallX,
+input [31:0] inbus, codebus,
+output [23:0] adr,
+output rd, wr, ben,
+output [31:0] outbus);
+
+localparam StartAdr = 22'h3FF800;
+
+reg [21:0] PC;
+reg [31:0] IR;  // instruction register
+reg N, Z, C, OV;  // condition flags 
+reg [31:0] H;  // aux register
+reg stallL1;
+
+wire [21:0] pcmux, pcmux0, nxpc;
+wire cond, S;
+wire sa, sb, sc;
+
+wire p, q, u, v;  // instruction fields
+wire [3:0] op, ira, ira0, irb, irc;
+wire [2:0] cc;
+wire [15:0] imm;
+wire [19:0] off;
+wire [21:0] disp;
+
+wire regwr;
+wire stall, stallL0, stallM, stallD, stallFA, stallFM, stallFD;
+wire nn, zz, cx, vv;
+
+reg irq1, intEnb, intPnd, intMd;
+reg [25:0] SPC; // saved PC on interrupt
+wire intAck;
+
+wire [31:0] A, B, C0, C1, aluRes, regmux, inbus1;
+wire [31:0] lshout, rshout;
+wire [31:0] quotient, remainder;
+wire [63:0] product;
+wire [31:0] fsum, fprod, fquot;
+
+wire ADD, SUB, MUL, DIV;
+wire FAD, FSB, FML, FDV;
+wire LDR, STR, BR, RTI;
+
+Registers regs (.clk(clk), .wr(regwr), .rno0(ira0), .rno1(irb),
+   .rno2(irc), .din(regmux), .dout0(A), .dout1(B), .dout2(C0));
+
+Multiplier mulUnit (.clk(clk), .run(MUL), .stall(stallM),
+   .u(~u), .x(B), .y(C1), .z(product));
+
+Divider divUnit (.clk(clk), .run(DIV), .stall(stallD),
+   .u(~u), .x(B), .y(C1), .quot(quotient), .rem(remainder));
+
+LeftShifter LSUnit (.x(B), .y(lshout), .sc(C1[4:0]));
+
+RightShifter RSUnit(.x(B), .y(rshout), .sc(C1[4:0]), .md(IR[16]));
+
+FPAdder fpaddx (.clk(clk), .run(FAD|FSB), .u(u), .v(v), .stall(stallFA),
+   .x(B), .y({FSB^C0[31], C0[30:0]}), .z(fsum));
+
+FPMultiplier fpmulx (.clk(clk), .run(FML), .stall(stallFM),
+   .x(B), .y(C0), .z(fprod));
+
+FPDivider fpdivx (.clk(clk), .run(FDV), .stall(stallFD),
+   .x(B), .y(C0), .z(fquot));
+
+assign p = IR[31];
+assign q = IR[30];
+assign u = IR[29];
+assign v = IR[28];
+assign cc  = IR[26:24];
+assign ira = IR[27:24];
+assign irb = IR[23:20];
+assign op  = IR[19:16];
+assign irc = IR[3:0];
+assign imm = IR[15:0];   // reg instr.
+assign off = IR[19:0];   // mem instr.
+assign disp = IR[21:0];  // branch instr.
+
+assign ADD = ~p & (op == 8);
+assign SUB = ~p & (op == 9);
+assign MUL = ~p & (op == 10);
+assign DIV = ~p & (op == 11);
+
+assign FAD = ~p & (op == 12);
+assign FSB = ~p & (op == 13);
+assign FML = ~p & (op == 14);
+assign FDV = ~p & (op == 15);
+
+assign LDR = p & ~q & ~u;
+assign STR = p & ~q & u;
+assign BR = p & q;
+assign RTI = BR & ~u & ~v & IR[4];
+
+// Arithmetic-logical unit (ALU)
+assign ira0 = BR ? 15 : ira;
+assign C1 = q ? {{16{v}}, imm} : C0;
+assign adr = stallL0 ? B[23:0] + {{4{off[19]}}, off} : {pcmux, 2'b00};
+assign rd = LDR & ~stallX & ~stallL1;
+assign wr = STR & ~stallX & ~stallL1;
+assign ben = p & ~q & v & ~stallX & ~stallL1;  // byte enable
+
+assign aluRes =
+  ~op[3] ?
+    (~op[2] ?
+      (~op[1] ?
+        (~op[0] ? 
+          (q ?  // MOV
+            (~u ? {{16{v}}, imm} : {imm, 16'b0}) :
+            (~u ? C0 : (~v ? H : {N, Z, C, OV, 20'b0, 8'h53}))) :
+          lshout) :  //  LSL
+        rshout) : //  ASR, ROR
+      (~op[1] ?
+        (~op[0] ? B & C1 : B & ~C1) :  // AND, ANN
+        (~op[0] ? B | C1 : B ^ C1))) : // IOR. XOR
+    (~op[2] ?
+       (~op[1] ?
+          (~op[0] ? B + C1 + (u&C) : B - C1 - (u&C)) :   // ADD, SUB
+           (~op[0] ? product[31:0] : quotient)) :  // MUL, DIV
+       (~op[1] ?    // flt.pt.
+          fsum :
+          (~op[0] ? fprod : fquot)));
+
+assign regwr = ~p & ~stall | (LDR & ~stallX & ~stallL1) | (BR & cond & v & ~stallX);
+assign inbus1 = ~ben ? inbus :
+  {24'b0, (adr[1] ? (adr[0] ? inbus[31:24] : inbus[23:16]) :
+          (adr[0] ? inbus[15:8] : inbus[7:0]))};
+assign regmux = LDR ? inbus1 : (BR & v) ? {8'b0, nxpc, 2'b0} : aluRes;
+assign outbus = ~ben ? A :
+  adr[1] ? (adr[0] ? {A[7:0], 24'b0} : {8'b0, A[7:0], 16'b0}) :
+           (adr[0] ? {16'b0, A[7:0], 8'b0} : {24'b0, A[7:0]});
+
+// Control unit CU
+assign S = N ^ OV;
+assign nxpc = PC + 1;
+assign cond = IR[27] ^
+  ((cc == 0) & N | // MI, PL
+   (cc == 1) & Z | // EQ, NE
+   (cc == 2) & C | // CS, CC
+   (cc == 3) & OV | // VS, VC
+   (cc == 4) & (C|Z) | // LS, HI
+   (cc == 5) & S | // LT, GE
+   (cc == 6) & (S|Z) | // LE, GT
+   (cc == 7)); // T, F
+
+assign intAck = intPnd & intEnb & ~intMd & ~stall;
+assign pcmux = ~rst | stall | intAck | RTI ? 
+   (~rst | stall ? (~rst ? StartAdr : PC) :
+   (intAck ? 1 : SPC)) : pcmux0;
+assign pcmux0 = (BR & cond) ? (u? nxpc + disp : C0[23:2]) : nxpc;
+  
+assign sa = aluRes[31];
+assign sb = B[31];
+assign sc = C1[31];
+
+assign nn = RTI ? SPC[25] : regwr ? regmux[31] : N;
+assign zz = RTI ? SPC[24] : regwr ? (regmux == 0) : Z;
+assign cx = RTI ? SPC[23] :
+    ADD ? (~sb&sc&~sa) | (sb&sc&sa) | (sb&~sa) :
+	 SUB ? (~sb&sc&~sa) | (sb&sc&sa) | (~sb&sa) : C;
+assign vv = RTI ? SPC[22] :
+    ADD ? (sa&~sb&~sc) | (~sa&sb&sc): 
+	 SUB ? (sa&~sb&sc) | (~sa&sb&~sc) : OV;
+	 
+assign stallL0 = (LDR|STR) & ~stallL1;
+assign stall = stallL0 | stallM | stallD | stallX | stallFA | stallFM | stallFD;
+
+always @ (posedge clk) begin
+  PC <= pcmux;
+  IR <= stall ? IR : codebus;
+  stallL1 <= stallX ? stallL1 : stallL0;
+  N <= nn; Z <= zz; C <= cx; OV <= vv;
+  H <= MUL ? product[63:32] : DIV ? remainder : H;
+
+  irq1 <= irq;  // edge detector
+  intPnd <= rst & ~intAck & ((~irq1 & irq) | intPnd);
+  intMd <= rst & ~RTI & (intAck | intMd);
+  intEnb <= ~rst ? 0 : (BR & ~u & ~v & IR[5]) ? IR[0] : intEnb;
+  SPC <= (intAck) ? {nn, zz, cx, vv, pcmux0} : SPC;
+  end 
+endmodule 

+ 146 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RISC5Top.v.html

@@ -0,0 +1,146 @@
+`timescale 1ns / 1ps  // 14.6.2018
+// with SRAM, and gpio
+// PS/2 mouse and network 7.1.2014 PDR
+
+module RISC5Top(
+  input CLK50M,
+  input [3:0] btn,
+  input [7:0] swi,
+  input  RxD,   // RS-232
+  output TxD,
+  output [7:0] leds,
+  output SRce0, SRce1, SRwe, SRoe,  //SRAM
+  output [3:0] SRbe,
+  output [17:0] SRadr,
+  inout [31:0] SRdat,
+  input [1:0] MISO,          // SPI - SD card & network
+  output [1:0] SCLK, MOSI,
+  output [1:0] SS,
+  output NEN,  // network enable
+  output hsync, vsync, // video controller
+  output [2:0] RGB,
+  input PS2C, PS2D,    // keyboard
+  inout msclk, msdat,
+  inout [7:0] gpio);
+
+// IO addresses for input / output
+// 0  -64  FFFFC0  milliseconds / --
+// 1  -60  FFFFC4  switches / LEDs
+// 2  -56  FFFFC8  RS-232 data / RS-232 data (start)
+// 3  -52  FFFFCC  RS-232 status / RS-232 control
+// 4  -48  FFFFD0  SPI data / SPI data (start)
+// 5  -44  FFFFD4  SPI status / SPI control
+// 6  -40  FFFFD8  PS2 mouse data, keyboard status / --
+// 7  -36  FFFFDC  keyboard data / --
+// 8  -32  FFFFE0  general-purpose I/O data
+// 9  -28  FFFFE4  general-purpose I/O tri-state control
+
+reg rst, clk;
+wire[23:0] adr;
+wire [3:0] iowadr; // word address
+wire [31:0] inbus, inbus0;  // data to RISC core
+wire [31:0] outbus;  // data from RISC core
+wire [31:0] romout, codebus;  // code to RISC core
+wire SRbe0, SRbe1;
+wire rd, wr, ben, ioenb, vidreq;
+
+wire [7:0] dataTx, dataRx, dataKbd;
+wire rdyRx, doneRx, startTx, rdyTx, rdyKbd, doneKbd;
+wire [27:0] dataMs;
+reg bitrate;  // for RS232
+wire limit;  // of cnt0
+
+reg [7:0] Lreg;
+reg [15:0] cnt0;
+reg [31:0] cnt1; // milliseconds
+
+wire [31:0] spiRx;
+wire spiStart, spiRdy;
+reg [3:0] spiCtrl;
+wire [17:0] vidadr;
+reg [7:0] gpout, gpoc;
+wire [7:0] gpin;
+
+RISC5 riscx(.clk(clk), .rst(rst), .irq(limit),
+   .rd(rd), .wr(wr), .ben(ben), .stallX(vidreq),
+   .adr(adr), .codebus(codebus), .inbus(inbus),
+	.outbus(outbus));
+PROM PM (.adr(adr[10:2]), .data(romout), .clk(~clk));
+RS232R receiver(.clk(clk), .rst(rst), .RxD(RxD), .fsel(bitrate),
+   .done(doneRx), .data(dataRx), .rdy(rdyRx));
+RS232T transmitter(.clk(clk), .rst(rst), .start(startTx),
+   .fsel(bitrate), .data(dataTx), .TxD(TxD), .rdy(rdyTx));
+SPI spi(.clk(clk), .rst(rst), .start(spiStart), .dataTx(outbus),
+   .fast(spiCtrl[2]), .dataRx(spiRx), .rdy(spiRdy),
+ 	.SCLK(SCLK[0]), .MOSI(MOSI[0]), .MISO(MISO[0] & MISO[1]));
+VID vid(.clk(clk), .req(vidreq), .inv(swi[7]),
+   .vidadr(vidadr), .viddata(inbus0), .RGB(RGB),
+	.hsync(hsync), .vsync(vsync));
+PS2 kbd(.clk(clk), .rst(rst), .done(doneKbd), .rdy(rdyKbd), .shift(),
+   .data(dataKbd), .PS2C(PS2C), .PS2D(PS2D));
+MouseP Ms(.clk(clk), .rst(rst), .msclk(msclk),
+   .msdat(msdat), .out(dataMs));
+
+assign codebus = (adr[23:14] == 10'h3FF) ? romout : inbus0;
+assign iowadr = adr[5:2];
+assign ioenb = (adr[23:6] == 18'h3FFFF);
+assign inbus = ~ioenb ? inbus0 :
+   ((iowadr == 0) ? cnt1 :
+    (iowadr == 1) ? {20'b0, btn, swi} :
+    (iowadr == 2) ? {24'b0, dataRx} :
+    (iowadr == 3) ? {30'b0, rdyTx, rdyRx} :
+    (iowadr == 4) ? spiRx :
+    (iowadr == 5) ? {31'b0, spiRdy} :
+    (iowadr == 6) ? {3'b0, rdyKbd, dataMs} :
+    (iowadr == 7) ? {24'b0, dataKbd} :
+    (iowadr == 8) ? {24'b0, gpin} :
+    (iowadr == 9) ? {24'b0, gpoc} : 0);
+	 
+assign SRce0 = ~(~ben | ~adr[1]);
+assign SRce1 = ~(~ben | adr[1]);
+assign SRbe0 = ~(~ben | ~adr[0]);
+assign SRbe1 = ~(~ben | adr[0]);
+assign SRwe = ~wr | clk;
+assign SRoe = wr;
+assign SRbe = {SRbe1, SRbe0, SRbe1, SRbe0};
+assign SRadr = vidreq ? vidadr : adr[19:2];
+
+genvar i;
+generate // tri-state buffer for SRAM
+  for (i = 0; i < 32; i = i+1)
+  begin: bufblock
+    IOBUF SRbuf (.I(outbus[i]), .O(inbus0[i]), .IO(SRdat[i]), .T(~wr));
+  end
+endgenerate
+
+generate // tri-state buffer for gpio port
+  for (i = 0; i < 8; i = i+1)
+  begin: gpioblock
+    IOBUF gpiobuf (.I(gpout[i]), .O(gpin[i]), .IO(gpio[i]), .T(~gpoc[i]));
+  end
+endgenerate
+
+assign dataTx = outbus[7:0];
+assign startTx = wr & ioenb & (iowadr == 2);
+assign doneRx = rd & ioenb & (iowadr == 2);
+assign limit = (cnt0 == 24999);
+assign leds = Lreg;
+assign spiStart = wr & ioenb & (iowadr == 4);
+assign SS = ~spiCtrl[1:0];  //active low slave select
+assign MOSI[1] = MOSI[0], SCLK[1] = SCLK[0], NEN = spiCtrl[3];
+assign doneKbd = rd & ioenb & (iowadr == 7);
+
+always @(posedge clk)
+begin
+  rst <= ((cnt1[4:0] == 0) & limit) ? ~btn[3] : rst;
+  Lreg <= ~rst ? 0 : (wr & ioenb & (iowadr == 1)) ? outbus[7:0] : Lreg;
+  cnt0 <= limit ? 0 : cnt0 + 1;
+  cnt1 <= cnt1 + limit;
+  spiCtrl <= ~rst ? 0 : (wr & ioenb & (iowadr == 5)) ? outbus[3:0] : spiCtrl;
+  bitrate <= ~rst ? 0 : (wr & ioenb & (iowadr == 3)) ? outbus[0] : bitrate;
+  gpout <= (wr & ioenb & (iowadr == 8)) ? outbus[7:0] : gpout;
+  gpoc <= ~rst ? 0 : (wr & ioenb & (iowadr == 9)) ? outbus[7:0] : gpoc;
+end
+
+always @ (posedge CLK50M) clk <= ~clk;
+endmodule

+ 147 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RISC5a.v.html

@@ -0,0 +1,147 @@
+`timescale 1ns / 1ps  // 1.9.2018
+//no interrupt, no floating-point
+
+module RISC5(
+input clk, rst, irq, stallX,
+input [31:0] inbus, codebus,
+output [23:0] adr,
+output rd, wr, ben,
+output [31:0] outbus);
+
+localparam StartAdr = 22'h3FF800;
+
+reg [21:0] PC;
+reg [31:0] IR;  // instruction register
+reg N, Z, C, OV;  // condition flags 
+reg [31:0] H;  // aux register
+reg stallL1;
+
+wire [21:0] pcmux, nxpc;
+wire cond, S;
+wire sa, sb, sc;
+
+wire p, q, u, v;  // instruction fields
+wire [3:0] op, ira, ira0, irb, irc;
+wire [2:0] cc;
+wire [15:0] imm;
+wire [19:0] off;
+wire [21:0] disp;
+
+wire regwr;
+wire stall, stallL0, stallM, stallD;
+wire [31:0] A, B, C0, C1, aluRes, regmux, inbus1;
+wire [31:0] lshout, rshout;
+wire [31:0] quotient, remainder;
+wire [63:0] product;
+
+wire ADD, SUB, MUL, DIV;
+wire LDR, STR, BR;
+
+Registers regs (.clk(clk), .wr(regwr), .rno0(ira0), .rno1(irb),
+   .rno2(irc), .din(regmux), .dout0(A), .dout1(B), .dout2(C0));
+
+Multiplier mulUnit (.clk(clk), .run(MUL), .stall(stallM),
+   .u(~u), .x(B), .y(C1), .z(product));
+
+Divider divUnit (.clk(clk), .run(DIV), .stall(stallD),
+   .u(~u), .x(B), .y(C1), .quot(quotient), .rem(remainder));
+
+LeftShifter LSUnit (.x(B), .y(lshout), .sc(C1[4:0]));
+
+RightShifter RSUnit(.x(B), .y(rshout), .sc(C1[4:0]), .md(IR[16]));
+
+assign p = IR[31];
+assign q = IR[30];
+assign u = IR[29];
+assign v = IR[28];
+assign cc  = IR[26:24];
+assign ira = IR[27:24];
+assign irb = IR[23:20];
+assign op  = IR[19:16];
+assign irc = IR[3:0];
+assign imm = IR[15:0];   // reg instr.
+assign off = IR[19:0];   // mem instr.
+assign disp = IR[21:0];  // branch instr.
+
+assign ADD = ~p & (op == 8);
+assign SUB = ~p & (op == 9);
+assign MUL = ~p & (op == 10);
+assign DIV = ~p & (op == 11);
+
+assign LDR = p & ~q & ~u;
+assign STR = p & ~q & u;
+assign BR = p & q;
+
+// Arithmetic-logical unit (ALU)
+assign ira0 = BR ? 15 : ira;
+assign C1 = q ? {{16{v}}, imm} : C0;
+assign adr = stallL0 ? B[23:0] + {{4{off[19]}}, off} : {pcmux, 2'b00};
+assign rd = LDR & ~stallX & stallL0;
+assign wr = STR & ~stallX & stallL0;
+assign ben = p & ~q & v & ~stallX & stallL0; // byte enable
+
+assign aluRes =
+  ~op[3] ?
+    (~op[2] ?
+      (~op[1] ?
+        (~op[0] ? 
+          (q ?  // MOV
+            (~u ? {{16{v}}, imm} : {imm, 16'b0}) :
+            (~u ? C0 : (~v ? H : {N, Z, C, OV, 20'b0, 8'h54}))) :
+          lshout) :  //  LSL
+        rshout) : //  ASR, ROR
+      (~op[1] ?
+        (~op[0] ? B & C1 : B & ~C1) :  // AND, ANN
+        (~op[0] ? B | C1 : B ^ C1))) : // IOR. XOR
+    (~op[2] ?
+       (~op[1] ?
+          (~op[0] ? B + C1 + (u&C) : B - C1 - (u&C)) : // ADD, SUB
+           (~op[0] ? product[31:0] : quotient)) :  // MUL, DIV
+        0);
+
+assign regwr = ~p & ~stall | (LDR & ~stallX & ~stallL1) | (BR & cond & v & ~stallX);
+assign inbus1 = ~ben ? inbus :
+  {24'b0, (adr[1] ? (adr[0] ? inbus[31:24] : inbus[23:16]) :
+          (adr[0] ? inbus[15:8] : inbus[7:0]))};
+assign regmux = LDR ? inbus1 : (BR & v) ? {8'b0, nxpc, 2'b0} : aluRes;
+assign outbus = ~ben ? A :
+  adr[1] ? (adr[0] ? {A[7:0], 24'b0} : {8'b0, A[7:0], 16'b0}) :
+           (adr[0] ? {16'b0, A[7:0], 8'b0} : {24'b0, A[7:0]});
+
+// Control unit CU
+assign S = N ^ OV;
+assign nxpc = PC + 1;
+assign cond = IR[27] ^
+  ((cc == 0) & N | // MI, PL
+   (cc == 1) & Z | // EQ, NE
+   (cc == 2) & C | // CS, CC
+   (cc == 3) & OV | // VS, VC
+   (cc == 4) & (C|Z) | // LS, HI
+   (cc == 5) & S | // LT, GE
+   (cc == 6) & (S|Z) | // LE, GT
+   (cc == 7)); // T, F
+
+assign pcmux = ~rst | stall ?
+  (~rst ? StartAdr : PC) :
+  (BR & cond) ? (u ? nxpc + disp : C0[23:2]) : nxpc;
+
+assign sa = aluRes[31];
+assign sb = B[31];
+assign sc = C1[31];
+
+assign stall = stallL0 | stallM | stallD | stallX;
+assign stallL0 = (LDR|STR) & ~stallL1;
+
+always @ (posedge clk) begin
+  PC <= pcmux;
+  IR <= stall ? IR : codebus;
+  stallL1 <= stallX ? stallL1 : stallL0;
+  N <= regwr ? regmux[31] : N;
+  Z <= regwr ? (regmux == 0) : Z;
+  C <= ADD ? (~sb&sc&~sa) | (sb&sc&sa) | (sb&~sa) :
+	 SUB ? (~sb&sc&~sa) | (sb&sc&sa) | (~sb&sa) : C;
+  OV <= ADD ? (sa&~sb&~sc) | (~sa&sb&sc): 
+	 SUB ? (sa&~sb&sc) | (~sa&sb&~sc) : OV;
+  H <= MUL ? product[63:32] : DIV ? remainder : H;
+end 
+endmodule 

+ 38 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RS232R.v.html

@@ -0,0 +1,38 @@
+`timescale 1ns / 1ps  // NW 4.5.09 / 15.11.10
+
+// RS232 receiver for 19200 or 115200 bps, 8 bit data
+// clock is 25 MHz

+
+module RS232R(
+    input clk, rst,
+	 input RxD,
+    input fsel,
+    input done,   // "byte has been read"
+    output rdy,
+    output [7:0] data);
+
+wire endtick, midtick, endbit;
+wire [11:0] limit;
+reg run, stat;
+reg Q0, Q1;  // synchronizer and edge detector
+reg [11:0] tick;
+reg [3:0] bitcnt;
+reg [7:0] shreg;
+
+assign limit = fsel ? 217 : 1302;
+assign endtick = tick == limit;
+assign midtick = tick == {1'b0, limit[11:1]};  // limit/2
+assign endbit = bitcnt == 8;
+assign data = shreg;
+assign rdy = stat;
+
+always @ (posedge clk) begin
+  Q0 <= RxD; Q1 <= Q0;
+  run <= (Q1 & ~Q0) | ~(~rst | endtick & endbit) & run;
+  tick <= (run & ~endtick) ? tick+1 : 0;
+  bitcnt <= (endtick & ~endbit) ? bitcnt + 1 :
+    (endtick & endbit) ? 0 : bitcnt;
+  shreg <= midtick ? {Q1, shreg[7:1]} : shreg;
+  stat <= (endtick & endbit) | ~(~rst | done) & stat;
+end
+endmodule

+ 35 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RS232T.v.html

@@ -0,0 +1,35 @@
+`timescale 1ns / 1ps  // NW 4.5.09 / 15.8.10 / 15.11.10
+
+// RS232 transmitter for 19200 bps, 8 bit data
+// clock is 25 MHz; 25000 / 1302 = 19.2 KHz
+
+module RS232T(
+    input clk, rst,
+    input start, // request to accept and send a byte
+	 input fsel,  // frequency selection
+    input [7:0] data,
+    output rdy,
+    output TxD);
+
+wire endtick, endbit;
+wire [11:0] limit;
+reg run;
+reg [11:0] tick;
+reg [3:0] bitcnt;
+reg [8:0] shreg;
+
+assign limit = fsel ? 217 : 1302;
+assign endtick = tick == limit;
+assign endbit = bitcnt == 9;
+assign rdy = ~run;
+assign TxD = shreg[0];
+
+always @ (posedge clk) begin
+  run <= (~rst | endtick & endbit) ? 0 : start ? 1 : run;
+  tick <= (run & ~endtick) ? tick + 1 : 0;
+  bitcnt <= (endtick & ~endbit) ? bitcnt + 1 :
+    (endtick & endbit) ? 0 : bitcnt;
+  shreg <= (~rst) ? 1 : start ? {data, 1'b0} :
+    endtick ? {1'b1, shreg[8:1]} : shreg;
+end
+endmodule

+ 46 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/Registers.v.html

@@ -0,0 +1,46 @@
+`timescale 1ns / 1ps  // 1.2.2018
+// register file, triple-port
+
+module Registers(
+  input clk,wr,
+  input [3:0] rno0, rno1, rno2,
+  input [31:0] din,
+  output [31:0] dout0, dout1, dout2);
+genvar i;
+generate    //triple port register file, duplicated LUT array
+	for (i = 0; i < 32; i = i+1)
+	begin: rf32
+	RAM16X1D # (.INIT(16'h0000))
+	rfb(
+	.DPO(dout1[i]), // data out
+	.SPO(dout0[i]),
+	.A0(rno0[0]),   // R/W address, controls D and SPO
+	.A1(rno0[1]),
+	.A2(rno0[2]),
+	.A3(rno0[3]),
+	.D(din[i]),  // data in
+	.DPRA0(rno1[0]), // read-only adr, controls DPO
+	.DPRA1(rno1[1]),
+	.DPRA2(rno1[2]),
+	.DPRA3(rno1[3]),
+	.WCLK(clk),
+	.WE(wr));
+
+	RAM16X1D # (.INIT(16'h0000))
+	rfc(
+	.DPO(dout2[i]), // data out
+	.SPO(),
+	.A0(rno0[0]),   // R/W address, controls D and SPO
+	.A1(rno0[1]),
+	.A2(rno0[2]),
+	.A3(rno0[3]),
+	.D(din[i]),  // data in
+	.DPRA0(rno2[0]), // read-only adr, controls DPO
+	.DPRA1(rno2[1]),
+	.DPRA2(rno2[2]),
+	.DPRA3(rno2[3]),
+	.WCLK(clk),
+	.WE(wr));
+	end
+endgenerate
+endmodule

+ 24 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/RightShifter.v.html

@@ -0,0 +1,24 @@
+`timescale 1ns / 1ps  // NW 9.11.2016
+
+module RightShifter(
+input [31:0] x,
+input [4:0] sc,
+input md,
+output [31:0] y);
+
+// shifter for ASR and ROR
+wire [1:0] sc0, sc1;
+wire [31:0] s1, s2;
+
+assign sc0 = sc[1:0];
+assign sc1 = sc[3:2];
+
+assign s1 = (sc0 == 3) ? {(md ? x[2:0] : {3{x[31]}}), x[31:3]} :
+    (sc0 == 2) ? {(md ? x[1:0] : {2{x[31]}}), x[31:2]} :
+    (sc0 == 1) ? {(md ? x[0] : x[31]), x[31:1]} : x;
+
+assign s2 = (sc1 == 3) ? {(md ? s1[11:0] : {12{s1[31]}}), s1[31:12]} :
+    (sc1 == 2) ? {(md ? s1[7:0] : {8{s1[31]}}), s1[31:8]} :
+    (sc1 == 1) ? {(md ? s1[3:0] : {4{s1[31]}}), s1[31:4]} : s1;
+assign y = sc[4] ? {(md ? s2[15:0] : {16{s2[31]}}), s2[31:16]} : s2;
+endmodule

+ 36 - 0
people.inf.ethz.ch/wirth/ProjectOberon/SourcesVerilog/SPI.v.html

@@ -0,0 +1,36 @@
+`timescale 1ns / 1ps
+
+// Motorola Serial Peripheral Interface (SPI) PDR 23.3.12 / 16.10.13
+// transmitter / receiver of words (fast, clk/3) or bytes (slow, clk/64)
+// e.g 8.33MHz or ~400KHz respectively at 25MHz (slow needed for SD-card init)
+// note: bytes are always MSbit first; but if fast, words are LSByte first
+
+module SPI(
+  input clk, rst,
+  input start, fast,
+  input [31:0] dataTx,
+  output [31:0] dataRx,
+  output reg rdy,
+  input MISO, output MOSI, output SCLK);
+
+wire endbit, endtick;
+reg [31:0] shreg;
+reg [5:0] tick;
+reg [4:0] bitcnt;
+
+assign endtick = fast ? (tick == 2) : (tick == 63);  //25MHz clk
+assign endbit = fast ? (bitcnt == 31) : (bitcnt == 7);
+assign dataRx = fast ? shreg : {24'b0, shreg[7:0]};
+assign MOSI = (~rst | rdy) ? 1 : shreg[7];
+assign SCLK = (~rst | rdy) ? 0 : fast ? endtick : tick[5];
+
+always @ (posedge clk) begin
+  tick <= (~rst | rdy | endtick) ? 0 : tick + 1;
+  rdy <= (~rst | endtick & endbit) ? 1 : start ? 0 : rdy;
+  bitcnt <= (~rst | start) ? 0 : (endtick & ~endbit) ? bitcnt + 1 : bitcnt;
+  shreg <= ~rst ? -1 : start ? dataTx : endtick ?
+    {shreg[30:24], MISO, shreg[22:16], shreg[31], shreg[14:8],
+       shreg[23], shreg[6:0], (fast ? shreg[15] : MISO)} : shreg;
+end
+
+endmodule