6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri May 03, 2024 2:13 am

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Fri Apr 25, 2014 2:00 pm 
Offline

Joined: Sat Dec 26, 2009 2:15 am
Posts: 39
Greetings all.

I've been trying to get a simple testBench and rom and ram modules working with Arlet's 6502 core.

I'm very much a noob with pl, and know only enough to be dangerous ;)

I have my tb, and rom at least compiled and running with both Iverilog and Xilinx tools (I don't have any FPGA boards yet), and am getting similar, and odd / unexpected results.

Sometimes the instructions are fetched, other times it seems like it's skipping cycles or something.

From what I've read here, it seems that real h.w. SRAMS can be tricky with this core, and maybe simulated ones as well ?

Is there a particular clk delay I should be using ?
I've just been guessing, and have experimented from #1 .. to #10 so far.

I have a cs(chip select) signal on my ram and roms and have experimented with both
an
Code:
always @(posedge clk) begin
if (cs ) begin
       tr1  =  address &  16'h0FFF ;
      $display ("(rom2)cs:%d address:%h tr1:%h data:%h",cs,address,tr1,data);
       data =  mem[tr1];
  end
end
,

and an
Code:
 always  @* begin
if (cs ) begin
       tr1  =  address &  16'h0FFF ;
      $display ("(rom2)cs:%d address:%h tr1:%h data:%h",cs,address,tr1,data);
       data =  mem[tr1];
  end
end


Here's the whole Rom :
Code:
module rom2(
cs,      // chip select
clk,     // clock
address, // Address input
data,    // Data output from ROM .. input to CPU
transAdd // debuggin of translated address
);

input cs,clk;
input      [15:0] address;
output reg [7:0]  data;
output     [15:0] transAdd;

reg [15:0] tr1;
reg [7:0]    mem [0:4096] ;

initial begin
  $readmemb("d:\\xilinx\\mike\\rom_data1.txt",mem);
end

always @(posedge clk) begin
  data = 8'hz;
  if (cs ) begin
       tr1  =  address &  16'h0FFF ;
       $display ("(rom2)cs:%d address:%h tr1:%h data:%h",cs,address,tr1,data);
       data =  mem[tr1];
  end
end
endmodule


Here's my tb :

Code:
`timescale 1s / 1us

module tb1();
 reg clk, reset;
 wire [15:0] AB;
 wire  [7:0] DI;
 wire [7:0] DO;
 wire WE;
 reg IRQ,NMI,RDY;
 wire [15:0] transAddr;
reg right;
reg [3:0] op;
reg [7:0] AI,BI;
reg CI,BCD;
wire [7:0] OUT;
wire CO,V,Z,N,HC;
wire [8*6-1:0] statename;
wire [5:0] state;
wire [15:0] PC;
wire [7:0] IR;

reg Ram1Reset,Ramz1cs;
reg Rom2cs;

// ---  DUTS -----

CPU cpu1( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY, state,PC,IR);
ALU alu1( clk, op, right, AI, BI, CI, CO, BCD, OUT, V, Z, N, HC, RDY );

rom2 Rom2(Rom2cs,
clk,
AB,
DI,
transAddr
);

RAMZ ramz1(Ramz1cs,
           clk,
           WE,
           Ram1Reset,
           AB,
           DO,
           DI
           );


initial begin
  $dumpfile( "cpu1.vcd" );
  $dumpvars( 0, tb1 );

  #1 clk       = 0;       // initial value of clock
  #1 reset     = 1;     // assert reset (active hi)

  #1 RDY     = 1;       // **** 0 = cpu stopped ***
  #100 reset = 0;    // De-assert the reset

  #1 Rom2cs = 1;
  #1 Ramz1cs = 0;     // disable ram

  #20240 $finish;      // Terminate simulation
end

always
   #10 clk = ~clk; // Toggle clock every 10 ticks

endmodule


The ram :
Code:
module RAMZ (     input cs,
                  input clk,
                  input WE,
                  input reset,
                  input [15:0] addr,
                  input [7:0] din,
                  output reg [7:0] dout
                  );

// reg [15:0] RAM [1023:0];
 reg [7:0] RAM [255:0];

initial begin
 $readmemh("ramz.txt",RAM);
 $monitor ("(RAMZ) cs:%h, clk:%h WE:%h, reset:%h addr:%h din:%h dout:%h",cs,clk,WE,reset,addr,din,dout);
end

always @(posedge clk) begin
  dout <= 8'hz;
 if (cs) begin
   if (WE)
      RAM[addr] <= din;
      else
         dout <= RAM[addr];
   if (reset)
      dout <= 0;

 end
end
endmodule


Mike


Top
 Profile  
Reply with quote  
PostPosted: Fri Apr 25, 2014 10:20 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Hi, first Arlet's core works fine with internal block RAMs/ROMs so you don't have to worry about delays are any other such things like you would when interfacing to external memory.

Second, I suspect your main machine is non functioning/interacting properly...
1st, you want a blockRAM/ROM to output logic '0's when they are not selected.
2nd, you want to wire-OR all the outputs from the blockRAM/ROM to the cpu data in.

I can check my projects and share some code when I get home tonight.

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Sat Apr 26, 2014 1:04 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Here is the code is use for stack RAM and zeropage RAM. 'rst' is hooked up to the address decoding, active low.
Code:
// 1Kx16 stack page FPGA blockRAM
`timescale 1ns / 1ps

module RAM ( input clk,
                  input we,
                  input rst,
                  input [9:0] addr,
                  input [15:0] din,
                  output reg [15:0] dout
                  );
               
reg [15:0] RAM [1023:0];

always @(posedge clk)
   if (we)
      RAM[addr] <= din;
      else
         dout <= rst ? 0 : RAM[addr];

endmodule

System ROM:
Code:
//4Kx16 ROM, i.e. initialized FPGA blockRAM
`timescale 1ns / 1ps

module ROM ( input clk,
             input rst,
             input [11:0] addr,
             output reg [15:0] dout
             );

reg [15:0] RAM [4095:0];

initial $readmemh("C:/65016PVBRAM/boot.coe",RAM,0,4095);

always @(posedge clk)
   dout <= rst ? 0 : RAM[addr];
               
endmodule


Hope this helps.

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Sat Apr 26, 2014 11:09 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
I just now realized I had copied/pasted my code from older code. I just now tested what I had posted and it failed... Only difference is this (similar in all modules) [OLD, fails]:
Code:
....dout <= rst ? 0 : RAM[addr]....;

[NEW, passes]:
Code:
dout <= rst ? 16'h0000 : RAM[addr];

Might want to try something similar in your code, i.e. specify the bit width for a '0'

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: