URL
https://opencores.org/ocsvn/thor/thor/trunk
Subversion Repositories thor
Compare Revisions
- This comparison shows the changes necessary to convert path
/thor
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/bench/Ps2Keyboard_sim.v
0,0 → 1,116
`timescale 1ns / 1ps |
// ============================================================================ |
// Ps2Keyboard.v - PS2 compatible keyboard interface |
// |
// 2015 Robert Finch |
// robfinch<remove>@finitron.ca |
// |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// Reg |
// 0 keyboard transmit/receive register |
// 1 status reg. itk xxxx p |
// i = interrupt status |
// t = transmit complete |
// k = transmit acknowledge receipt (from keyboard) |
// p = parity error |
// A write to the status register clears the transmitter |
// state |
// |
// ============================================================================ |
// |
module Ps2Keyboard_sim(rst_i, clk_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o, kclk, kd, irq_o); |
parameter pIOAddress = 32'hFFDC0000; |
parameter pAckStyle = 1'b0; |
input rst_i; |
input clk_i; |
input cyc_i; |
input stb_i; |
output ack_o; |
input we_i; |
input [31:0] adr_i; |
input [7:0] dat_i; |
output reg [7:0] dat_o; |
inout tri kclk; |
inout tri kd; |
output irq_o; |
|
reg rd; |
wire write_data; |
wire cs_kbd = cyc_i & stb_i && adr_i[31:4]==pIOAddress[31:4]; |
assign ack_o = cs_kbd; |
assign irq_o = rd; |
reg read_data; |
reg busy; |
reg err; |
reg [7:0] rx_data; |
reg [19:0] cnt; |
always @(posedge clk_i) |
if (rst_i) |
cnt <= 20'd0; |
else |
cnt <= cnt + 1; |
|
always @(posedge clk_i) |
if (rst_i) begin |
read_data <= 1'b0; |
rx_data <= 8'h00; |
busy <= 1'b0; |
err <= 1'b0; |
end |
else begin |
read_data <= 0; |
case(cnt) |
300: |
begin |
read_data <= 1'b1; |
rx_data <= 8'h41; |
end |
350: |
begin |
read_data <= 1'b1; |
rx_data <= 8'h42; |
end |
400: |
begin |
read_data <= 1'b1; |
rx_data <= 8'h43; |
end |
endcase |
end |
|
always @(posedge clk_i) |
if (rst_i) |
rd <= 1'b0; |
else begin |
if (read_data) |
rd <= 1'b1; |
else if (cs_kbd & ~we_i) |
rd <= 1'b0; |
end |
|
always @* |
if (cs_kbd & ~we_i) begin |
if (adr_i[0]) |
dat_o <= {rd,busy,5'b0,err}; |
else |
dat_o <= rx_data; |
end |
else |
dat_o <= 8'h00; |
|
assign write_data = cs_kbd & we_i & ~adr_i[0]; |
|
endmodule |
/trunk/bench/bootrom.v
0,0 → 1,114
`timescale 1ns / 1ps |
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2012-2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
module bootrom(rst_i, clk_i, cti_i, cyc_i, stb_i, ack_o, adr_i, dat_o, perr); |
parameter DBW=64; |
parameter MAGIC1=32'hAAAAAAAA; |
parameter MAGIC2=32'h55555555; |
input rst_i; |
input clk_i; |
input [2:0] cti_i; |
input cyc_i; |
input stb_i; |
output ack_o; |
input [31:0] adr_i; |
output [DBW-1:0] dat_o; |
reg [DBW-1:0] dat_o; |
output perr; |
reg perr; |
|
wire ne_cs; |
wire cs; |
reg ack0,ack1,ack2,ack3; |
always @(posedge clk_i) |
begin |
if (ne_cs) |
ack0 <= cs; |
else if (!cs) |
ack0 <= 1'b0; |
ack1 <= ack0 & cs; |
ack2 <= ack1 & cs; |
ack3 <= ack2 & cs; |
end |
assign cs = cyc_i && stb_i && adr_i[31:16]==16'hFFFF; |
assign ack_o = cs & ack0; |
|
reg [DBW:0] rommem0 [0:8191]; |
reg [DBW:0] rommem1 [0:8191]; |
reg [DBW:0] rommem2 [0:8191]; |
initial begin |
if (DBW==32) begin |
`include "..\..\software\A64\bin\boot.ve0" |
`include "..\..\software\A64\bin\boot.ve1" |
`include "..\..\software\A64\bin\boot.ve2" |
end |
else begin |
`include "..\..\software\a64\bin\boot.ve0" |
`include "..\..\software\A64\bin\boot.ve1" |
`include "..\..\software\A64\bin\boot.ve2" |
end |
end |
|
wire pe_cs; |
edge_det u1 (.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(cs), .pe(pe_cs), .ne(), .ee()); |
edge_det u2 (.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(pe_cs), .pe(), .ne(ne_cs), .ee()); |
|
reg [14:2] radr; |
reg [14:2] ctr; |
|
always @(posedge clk_i) |
if (pe_cs) begin |
if (DBW==32) |
ctr <= adr_i[14:2] + 13'd1; |
else |
ctr <= adr_i[14:3] + 13'd1; |
end |
else if (cs) |
ctr <= ctr + 13'd1; |
|
always @(posedge clk_i) |
if (DBW==32) |
radr <= pe_cs ? adr_i[14:2] : ctr; |
else |
radr <= pe_cs ? adr_i[14:3] : ctr; |
|
wire [31:0] d0 = rommem0[radr][DBW-1:0]; |
wire [31:0] d1 = rommem1[radr][DBW-1:0]^MAGIC1; |
wire [31:0] d2 = rommem2[radr][DBW-1:0]^MAGIC2; |
wire [31:0] d4 = (d0&d1)|(d0&d2)|(d1&d2); |
|
always @(posedge clk_i) |
if (cs) begin |
dat_o <= d4; |
$display("br read: %h %h", radr,d4); |
end |
else |
dat_o <= {DBW{1'b0}}; |
|
always @(posedge clk_i) |
if (cs) |
perr <= ^rommem0[radr][DBW-1:0]!=rommem0[radr][DBW]; |
else |
perr <= 1'd0; |
|
endmodule |
/trunk/bench/Thor_tb.v
0,0 → 1,213
|
module Thor_tb(); |
parameter DBW=32; |
reg rst; |
reg clk; |
reg nmi; |
reg p100Hz; |
wire [2:0] cti; |
wire cpu_clk; |
wire cyc; |
wire stb; |
wire we; |
wire [7:0] sel; |
wire br_ack; |
wire [31:0] adr; |
wire [DBW-1:0] br_dato; |
wire scr_ack; |
wire [63:0] scr_dato; |
|
wire cpu_ack; |
wire [DBW-1:0] cpu_dati; |
wire [DBW-1:0] cpu_dato; |
wire pic_ack,irq; |
wire [31:0] pic_dato; |
wire [7:0] vecno; |
|
wire LEDS_ack; |
|
initial begin |
#0 rst = 1'b0; |
#0 clk = 1'b0; |
#0 nmi = 1'b0; |
#0 p100Hz = 1'b0; |
#10 rst = 1'b1; |
#50 rst = 1'b0; |
#19550 nmi = 1'b1; |
#20 nmi = 1'b0; |
end |
|
always #5 clk = ~clk; |
always #10000 p100Hz = ~p100Hz; |
|
assign LEDS_ack = cyc && stb && adr[31:8]==32'hFFDC06; |
always @(posedge clk) |
if (LEDS_ack) |
$display("LEDS: %b", cpu_dato[7:0]); |
|
wire tc1_ack, tc2_ack; |
wire kbd_ack; |
wire [31:0] tc1_dato, tc2_dato; |
wire [7:0] kbd_dato; |
|
//wire cs0 = cyc&& stb && adr[31:16]==16'h0000; |
|
assign cpu_ack = |
LEDS_ack | |
scr_ack | |
br_ack | |
tc1_ack | tc2_ack | |
kbd_ack | pic_ack |
; |
assign cpu_dati = |
scr_dato | |
br_dato | |
tc1_dato | tc2_dato | |
{4{kbd_dato}} | |
pic_dato |
; |
|
Ps2Keyboard_sim ukbd |
( |
.rst_i(rst), |
.clk_i(cpu_clk), |
.cyc_i(cyc), |
.stb_i(stb), |
.ack_o(kbd_ack), |
.we_i(we), |
.adr_i(adr), |
.dat_i(cpu_dato), |
.dat_o(kbd_dato), |
.kclk(), |
.kd(), |
.irq_o() |
); |
|
rtfTextController3 #(.num(1), .pTextAddress(32'hFFD00000)) tc1 |
( |
.rst_i(rst), |
.clk_i(cpu_clk), |
.cyc_i(cyc), |
.stb_i(stb), |
.ack_o(tc1_ack), |
.we_i(we), |
.adr_i(adr), |
.dat_i(cpu_dato), |
.dat_o(tc1_dato), |
.lp(), |
.curpos(), |
.vclk(), |
.hsync(), |
.vsync(), |
.blank(), |
.border(), |
.rgbIn(), |
.rgbOut() |
); |
|
rtfTextController3 #(.num(1), .pTextAddress(32'hFFD10000)) tc2 |
( |
.rst_i(rst), |
.clk_i(cpu_clk), |
.cyc_i(cyc), |
.stb_i(stb), |
.ack_o(tc2_ack), |
.we_i(we), |
.adr_i(adr), |
.dat_i(cpu_dato), |
.dat_o(tc2_dato), |
.lp(), |
.curpos(), |
.vclk(), |
.hsync(), |
.vsync(), |
.blank(), |
.border(), |
.rgbIn(), |
.rgbOut() |
); |
|
scratchmem32 #(DBW) uscrm1 |
( |
.rst_i(rst), |
.clk_i(cpu_clk), |
.cyc_i(cyc), |
.stb_i(stb), |
.ack_o(scr_ack), |
.we_i(we), |
.sel_i(sel), |
.adr_i({32'd0,adr}), |
.dat_i(cpu_dato), |
.dat_o(scr_dato) |
); |
|
bootrom #(DBW) ubr1 |
( |
.rst_i(rst), |
.clk_i(cpu_clk), |
.cti_i(cti), |
.cyc_i(cyc), |
.stb_i(stb), |
.ack_o(br_ack), |
.adr_i(adr), |
.dat_o(br_dato), |
.perr() |
); |
|
wire nmio; |
Thor_pic upic1 |
( |
.rst_i(rst), // reset |
.clk_i(cpu_clk), // system clock |
.cyc_i(cyc), // cycle valid |
.stb_i(stb), // strobe |
.ack_o(pic_ack), // transfer acknowledge |
.we_i(we), // write |
.adr_i(adr), // address |
.dat_i(cpu_dato), |
.dat_o(pic_dato), |
.vol_o(), // volatile register selected |
.i1(), |
.i2(p100Hz), |
.i3(), |
.i4(), |
.i5(), |
.i6(), |
.i7(), |
.i8(), |
.i9(), |
.i10(), |
.i11(), |
.i12(), |
.i13(), |
.i14(), |
.i15(), |
.irqo(irq), // normally connected to the processor irq |
.nmii(nmi), // nmi input connected to nmi requester |
.nmio(nmio), // normally connected to the nmi of cpu |
.vecno(vecno) |
); |
|
Thor #(DBW) uthor1 |
( |
.rst_i(rst), |
.clk_i(clk), |
.clk_o(cpu_clk), |
.nmi_i(nmio), |
.irq_i(irq), |
.vec_i(vecno), |
.bte_o(), |
.cti_o(cti), |
.bl_o(), |
.cyc_o(cyc), |
.stb_o(stb), |
.ack_i(cpu_ack), |
.err_i(1'b0), |
.we_o(we), |
.sel_o(sel), |
.adr_o(adr), |
.dat_i(cpu_dati), |
.dat_o(cpu_dato) |
); |
|
endmodule |
/trunk/bench/scratchmem.v
0,0 → 1,178
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2012-2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
module scratchmem(rst_i, clk_i, cyc_i, stb_i, ack_o, we_i, sel_i, adr_i, dat_i, dat_o); |
parameter DBW=64; |
input rst_i; |
input clk_i; |
input cyc_i; |
input stb_i; |
output ack_o; |
input we_i; |
input [DBW/8-1:0] sel_i; |
input [DBW-1:0] adr_i; |
input [DBW-1:0] dat_i; |
output [DBW-1:0] dat_o; |
reg [DBW-1:0] dat_o; |
|
integer n; |
|
reg [7:0] smemA [2047:0]; |
reg [7:0] smemB [2047:0]; |
reg [7:0] smemC [2047:0]; |
reg [7:0] smemD [2047:0]; |
generate |
begin |
if (DBW==64) begin |
reg [7:0] smemE [2047:0]; |
reg [7:0] smemF [2047:0]; |
reg [7:0] smemG [2047:0]; |
reg [7:0] smemH [2047:0]; |
|
initial begin |
for (n = 0; n < 2048; n = n + 1) |
begin |
smemA[n] = 0; |
smemB[n] = 0; |
smemC[n] = 0; |
smemD[n] = 0; |
smemE[n] = 0; |
smemF[n] = 0; |
smemG[n] = 0; |
smemH[n] = 0; |
end |
end |
end |
else begin |
initial begin |
for (n = 0; n < 2048; n = n + 1) |
begin |
smemA[n] = 0; |
smemB[n] = 0; |
smemC[n] = 0; |
smemD[n] = 0; |
end |
end |
end |
end |
endgenerate |
reg [13:3] radr; |
|
|
wire cs = cyc_i && stb_i && adr_i[59:16]==44'h0000; |
|
reg rdy,rdy1; |
always @(posedge clk_i) |
begin |
rdy1 <= cs; |
rdy <= rdy1 & cs; |
end |
assign ack_o = cs ? (we_i ? 1'b1 : rdy) : 1'b0; |
|
|
always @(posedge clk_i) |
if (cs & we_i) |
$display ("wrote to scratchmem: %h=%h", adr_i, dat_i); |
generate |
begin |
if (DBW==64) begin |
always @(posedge clk_i) |
if (cs & we_i & sel_i[0]) |
smemA[adr_i[13:3]] <= dat_i[7:0]; |
always @(posedge clk_i) |
if (cs & we_i & sel_i[1]) |
smemB[adr_i[13:3]] <= dat_i[15:8]; |
always @(posedge clk_i) |
if (cs & we_i & sel_i[2]) |
smemC[adr_i[13:3]] <= dat_i[23:16]; |
always @(posedge clk_i) |
if (cs & we_i & sel_i[3]) |
smemD[adr_i[13:3]] <= dat_i[31:24]; |
//always @(posedge clk_i) |
// if (cs & we_i & sel_i[4]) |
// smemE[adr_i[13:3]] <= dat_i[39:32]; |
//always @(posedge clk_i) |
// if (cs & we_i & sel_i[5]) |
// smemF[adr_i[13:3]] <= dat_i[47:40]; |
//always @(posedge clk_i) |
// if (cs & we_i & sel_i[6]) |
// smemG[adr_i[13:3]] <= dat_i[55:48]; |
//always @(posedge clk_i) |
// if (cs & we_i & sel_i[7]) |
// smemH[adr_i[13:3]] <= dat_i[63:56]; |
end |
else begin |
always @(posedge clk_i) |
if (cs & we_i & sel_i[0]) |
smemA[adr_i[12:2]] <= dat_i[7:0]; |
always @(posedge clk_i) |
if (cs & we_i & sel_i[1]) |
smemB[adr_i[12:2]] <= dat_i[15:8]; |
always @(posedge clk_i) |
if (cs & we_i & sel_i[2]) |
smemC[adr_i[12:2]] <= dat_i[23:16]; |
always @(posedge clk_i) |
if (cs & we_i & sel_i[3]) |
smemD[adr_i[12:2]] <= dat_i[31:24]; |
end |
end |
endgenerate |
|
wire pe_cs; |
edge_det u1(.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(cs), .pe(pe_cs), .ne(), .ee() ); |
|
reg [13:3] ctr; |
always @(posedge clk_i) |
if (pe_cs) begin |
if (DBW==64) |
ctr <= adr_i[13:3] + 12'd1; |
else |
ctr <= adr_i[12:2] + 12'd1; |
end |
else if (cs) |
ctr <= ctr + 12'd1; |
|
always @(posedge clk_i) |
if (DBW==64) |
radr <= pe_cs ? adr_i[13:3] : ctr; |
else |
radr <= pe_cs ? adr_i[12:2] : ctr; |
|
//assign dat_o = cs ? {smemH[radr],smemG[radr],smemF[radr],smemE[radr], |
// smemD[radr],smemC[radr],smemB[radr],smemA[radr]} : 64'd0; |
|
always @(posedge clk_i) |
if (cs) begin |
// if (DBW==64) |
// dat_o <= {smemH[radr],smemG[radr],smemF[radr],smemE[radr], |
// smemD[radr],smemC[radr],smemB[radr],smemA[radr]}; |
// else |
dat_o <= {smemD[radr],smemC[radr],smemB[radr],smemA[radr]}; |
// if (!we_i) |
// $display("read from scratchmem: %h=%h", radr, {smemH[radr],smemG[radr],smemF[radr],smemE[radr], |
// smemD[radr],smemC[radr],smemB[radr],smemA[radr]}); |
end |
else |
dat_o <= {DBW{1'd0}}; |
|
endmodule |