URL
https://opencores.org/ocsvn/mc6803/mc6803/trunk
Subversion Repositories mc6803
Compare Revisions
- This comparison shows the changes necessary to convert path
/mc6803
- from Rev 4 to Rev 5
- ↔ Reverse comparison
Rev 4 → Rev 5
/trunk/MC6803_gen2.sv
0,0 → 1,259
module MC6803_gen2( |
input logic clk, |
RST, |
hold, |
halt, |
irq, |
nmi, |
input logic[7:0] PORT_A_IN, |
input logic[4:0] PORT_B_IN, |
input logic[7:0] DATA_IN, |
output logic[7:0] PORT_A_OUT, |
output logic[4:0] PORT_B_OUT, |
output logic[15:0] ADDRESS, |
output logic[7:0] DATA_OUT, |
output logic E_CLK, rw); |
|
logic[7:0] DATA_IN_s, PORT_A_IN_s; |
logic[4:0] PORT_B_IN_s; |
logic[7:0] data_in; |
logic hold_s, halt_s, irq_s, nmi_s; |
|
logic DDR1_E, DDR2_E, P1_E, P2_E, TCS_E, CH_E, CL_E, OCRH_E, OCRL_E, iRAM_E; |
logic OCF, next_OCF, TOF, next_TOF, EICI, next_EICI, EOCI, next_EOCI, ETOI, next_ETOI, IEDG, next_IEDG, OLVL, next_OLVL; |
logic irq_tof, irq_ocf; |
logic[7:0] next_port_a, next_DDR1, DDR1; |
logic[4:0] next_port_b, next_DDR2, DDR2; |
logic[15:0] counter, next_counter; |
logic[7:0] OCRH, OCRL, next_OCRH, next_OCRL; |
logic REG_RW; |
logic[7:0] REG_DATA; |
logic TOF_reset, OCF_reset; |
|
cpu01 cpu01_inst(.clk(clk), .rst(RST), .rw(rw), .vma(E_CLK), .address(ADDRESS), .data_in(data_in), .data_out(DATA_OUT), .hold(hold_s), .halt(halt_s), .irq(irq_s), .nmi(nmi_s), .irq_icf(1'b0), .irq_ocf(irq_ocf), .irq_tof(irq_tof), .irq_sci(1'b0)); |
|
MEM_128_8 iMEM(.Clk(clk), .reset(RST), .data_in(DATA_OUT), .data_out(REG_DATA), .RW(REG_RW), .address(ADDRESS[6:0])); |
|
always_ff @(negedge clk) |
begin |
if(RST) |
begin |
counter <= 0; |
OCF <= 0; |
EICI <= 0; |
EOCI <= 0; |
ETOI <= 0; |
IEDG <= 0; |
OLVL <= 0; |
OCRH <= 0; |
OCRL <= 0; |
end |
else |
begin |
DATA_IN_s <= DATA_IN; |
PORT_A_IN_s <= PORT_A_IN; |
PORT_B_IN_s <= PORT_B_IN; |
hold_s <= hold; |
halt_s <= halt; |
irq_s <= irq; |
nmi_s <= nmi; |
EICI <= next_EICI; |
EOCI <= next_EOCI; |
ETOI <= next_ETOI; |
IEDG <= next_IEDG; |
OLVL <= next_OLVL; |
PORT_A_OUT <= next_port_a; |
PORT_B_OUT <= next_port_b; |
counter <= next_counter; |
OCRH <= next_OCRH; |
OCRL <= next_OCRL; |
DDR1 <= next_DDR1; |
DDR2 <= next_DDR2; |
//timer resets |
end |
if(TCS_E & rw & TOF) |
TOF_reset <= 1'b1; |
if(TOF_reset & rw & CH_E) |
begin |
TOF <= 1'b0; |
TOF_reset <= 1'b0; |
end |
else |
TOF <= next_TOF; |
if(TCS_E & rw & OCF) |
OCF_reset <= 1'b1; |
if(OCF_reset & (~rw) & (OCRH_E | OCRL_E)) |
begin |
OCF <= 1'b0; |
OCF_reset <= 1'b0; |
end |
else |
OCF <= next_OCF; |
end |
|
always_comb |
begin |
if(ADDRESS > 16'h7f && ADDRESS < 16'h100 && E_CLK) |
iRAM_E = 1'b1; |
else |
iRAM_E = 0; |
DDR1_E = 1'b0; |
DDR2_E = 1'b0; |
P1_E = 1'b0; |
P2_E = 1'b0; |
TCS_E = 1'b0; |
CH_E = 1'b0; |
CL_E = 1'b0; |
OCRH_E = 1'b0; |
OCRL_E = 1'b0; |
//ICRH_E = 1'b0; |
//ICRL_E = 1'b0; |
data_in = DATA_IN_s; |
next_port_a = PORT_A_OUT; |
next_port_b = PORT_B_OUT; |
next_DDR1 = DDR1; |
next_DDR2 = DDR2; |
irq_tof = 1'b0; |
irq_ocf = 1'b0; |
next_EICI = EICI; |
next_OCRH = OCRH; |
next_OCRL = OCRL; |
next_EOCI = EOCI; |
next_ETOI = ETOI; |
next_IEDG = IEDG; |
next_OLVL = OLVL; |
REG_RW = 1'b1; |
|
case (ADDRESS) |
16'h00: DDR1_E = 1'b1; |
16'h01: DDR2_E = 1'b1; |
16'h02: P1_E = 1'b1; |
16'h03: P2_E = 1'b1; |
16'h08: TCS_E = 1'b1; |
16'h09: CH_E = 1'b1; |
16'h0A: CL_E = 1'b1; |
16'h0B: OCRH_E = 1'b1; |
16'h0C: OCRL_E = 1'b1; |
// 16'h0D: ICRH_E = 1'b1; |
// 16'h0E: ICRL_E = 1'b1; |
default: ; |
endcase |
|
// port A |
if(P1_E) |
begin |
data_in = (PORT_A_IN_s & (~DDR1))|(PORT_A_OUT & (DDR1)); |
if(E_CLK & (~rw)) |
next_port_a = DATA_OUT; |
else |
next_port_a = PORT_A_OUT; |
end |
if(DDR1_E) |
begin |
data_in = DDR1; |
if(E_CLK & (~rw)) |
next_DDR1 = DATA_OUT; |
else |
next_DDR1 = DDR1; |
end |
//port B |
if(P2_E) |
begin |
data_in = (PORT_B_IN_s & (~DDR2))|(PORT_B_OUT & (DDR2)); |
if(E_CLK & (~rw)) |
next_port_b = DATA_OUT[4:0]; |
else |
next_port_b = PORT_B_OUT; |
end |
if(DDR2_E) |
begin |
data_in = DDR2; |
if(E_CLK & (~rw)) |
next_DDR2 = DATA_OUT[4:0]; |
else |
next_DDR2 = DDR2; |
end |
// programmable timer |
//counter |
next_counter = counter + 16'h01; |
if(CH_E & E_CLK & (~rw)) |
next_counter = 16'hFFF8; |
if(counter == 16'hFFFF) |
begin |
next_TOF = 1'b1; |
irq_tof = ETOI; |
end |
else |
next_TOF = TOF; |
if(CH_E) |
data_in = counter[15:8]; |
if(CL_E) |
data_in = counter[7:0]; |
// output compare |
if(OCRH_E) |
begin |
data_in = OCRH; |
if(E_CLK & (~rw)) |
next_OCRH = DATA_OUT; |
else |
next_OCRH = OCRH; |
end |
if(OCRL_E) |
begin |
data_in = OCRL; |
if(E_CLK & (~rw)) |
next_OCRL = DATA_OUT; |
else |
next_OCRL = OCRL; |
end |
if(next_counter == {OCRH, OCRL}) |
begin |
next_OCF = 1'b1; |
irq_ocf = EOCI; |
end |
else |
next_OCF = OCF; |
// control and status |
if(TCS_E) |
begin |
data_in = {1'b0, OCF, TOF, EICI, EOCI, ETOI, IEDG, OLVL}; |
if(E_CLK & (~rw)) |
begin |
next_EICI = DATA_OUT[4]; |
next_EOCI = DATA_OUT[3]; |
next_ETOI = DATA_OUT[2]; |
next_IEDG = DATA_OUT[1]; |
next_OLVL = DATA_OUT[0]; |
end |
else |
begin |
next_EICI = EICI; |
next_EOCI = EOCI; |
next_ETOI = ETOI; |
next_IEDG = IEDG; |
next_OLVL = OLVL; |
end |
end |
//internal memory |
if(iRAM_E) |
begin |
data_in = REG_DATA; |
REG_RW = rw; |
end |
end |
|
endmodule |
|
module MEM_128_8(input logic[6:0] address, input logic RW, Clk, reset, input logic[7:0] data_in, output logic[7:0] data_out); |
logic[7:0] REGS[127:0]; |
integer i; |
always_ff @ (posedge Clk) |
begin |
if(reset) |
for(i=0; i<128; i=i+1) |
REGS[i]=0; |
else if(~RW) |
REGS[address] <= data_in; |
end |
assign data_out = REGS[address]; |
endmodule |
/trunk/readme.txt
0,0 → 1,4
File descriptions: |
6801_core.sv: CPU core file translated from VHDL. |
MC6803.sv: Old implementation of IO ports and timer of the MC6803 chip. This file will no longer be updated. |
MC6803_gen2: New implementation of IO ports and timer with bug fixes. |