Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Problems with Verilog bit array.....

Status
Not open for further replies.

PhillHS

Newbie level 1
Joined
Mar 20, 2017
Messages
1
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
23
Hi all,

I'm making an addon for an old 6809 based computer, one of the components of this machine (Tandy CoCo) has an IC that is programmed by writing to a series of addresses.
It has 16 programable bits that are programmed by writing to a pair of addresses, for example the first bit is programmed by writing to FFC0 (clear) and FFC1 to set.
Since this chip (74LS783 SAM) has no connection to the data bus of the machine I have no way of reading the values back, so my design has an XC95144XL CPLD attached to
the machine's bus.

I have defined a 16 bit word to capture the bits as written, it can be seen from above that once a suitable address range is decoded I should be able to use bits 4:1 of the address bus
as a 'register select' and address bit 0 effectivly becomes the data bit.

Once stored I need to be able to read back the data bits as two bytes.

The relevent bits of my code are posted below

Code:
module Main(
	// 6809 side
    input [15:0] Addr,		// Dragon address bus
    inout [7:0] Data,		// Daragon data bus
    input E,				// E clock
	input Q,				// Q clock
    input RW,				// Read/Write
    input Reset,			// System reset

    );
	
	reg	[15:0]	SAMBits;		// 1 bit x 16 bit array.....
	
	// Generate OE and WE signals, only do this if Reset is high ! 
	assign RD			= E & RW & Reset;
	assign WR			= E & ~RW & Reset;

	assign SAMBitsAddr	= ((Addr>=16'hFFC0) && (Addr<=16'hFFDF));
	assign SAMBitsWR	= SAMBitsAddr & WR;
	
	always @(posedge SAMBitsAddr or negedge Reset)
	begin
	  if (!Reset)
	  begin
	    case (Addr[5:1])
			4'b0000		: SAMBits[0]	<= Addr[0];
			4'b0001		: SAMBits[1]	<= Addr[0];
			4'b0010		: SAMBits[2]	<= Addr[0];
			4'b0011		: SAMBits[3]	<= Addr[0];
			4'b0100		: SAMBits[4]	<= Addr[0];
			4'b0101		: SAMBits[5]	<= Addr[0];
			4'b0110		: SAMBits[6]	<= Addr[0];
			4'b0111		: SAMBits[7]	<= Addr[0];
			4'b1000		: SAMBits[8]	<= Addr[0];
			4'b1001		: SAMBits[9]	<= Addr[0];
			4'b1010		: SAMBits[10]	<= Addr[0];
			4'b1011		: SAMBits[11]	<= Addr[0];
			4'b1100		: SAMBits[12]	<= Addr[0];
			4'b1101		: SAMBits[13]	<= Addr[0];
			4'b1110		: SAMBits[14]	<= Addr[0];
			4'b1111		: SAMBits[15]	<= Addr[0];
		endcase
	  end
	  else
	  begin
	    SAMBits[15:0] <= 0;
	  end
	end
	
	assign SAMBitsH		= (Addr==16'hFF58);
	assign SAMBitsL		= (Addr==16'hFF59);
	
	assign SAMBitsRD	= (SAMBitsL | SAMBitsH) & RD;
	wire [7:0]	SAMData;
	
	assign SAMData		= SAMBitsL ? { SAMBits[7], SAMBits[6], SAMBits[5], SAMBits[4], SAMBits[3], SAMBits[2], SAMBits[1], SAMBits[0]} :
									 { SAMBits[15], SAMBits[14], SAMBits[13], SAMBits[12], SAMBits[11], SAMBits[10], SAMBits[9], SAMBits[8]}; 
									 

	// When the Dragon reads give it the AVR data / status
	// Note both reading the AVR data reg & the PIA override give the AVRToDragon reg.
	wire [7:0] 	DragonDataOut;
	assign 	DragonDataOut[7:0]		= SAMBitsRD ? SAMData :
									  AVRStatus ? {5'b0,AVRW_DragonR,DragonW_AVRR,AVRBusy} : 
									  RamCTRLRD	? {MapMode,NMIEn,RAMVec,ROMA14, RomWE, FIRQEn, RamWP, RamEnable} :
											AVRToDragon;
	
	assign 	Data					= (DragonIORD | AVRStatusRD | RamCTRLRD | SAMBitsRD | PIACS) ? DragonDataOut : 8'bz;
endmodule

Note this module also handles other interfacing like enabling disabling roms and data exchange with an AVR microcontroller however that part of the design is working correctly
so I have trimmed if from the above code for clarity.

The above code does compile and fit into the chip however when looking at the output equations it all seems to be implemented as FTCPE, which doesn't seem to make sense, as
I'm not asking it to toggle :(

This is the code generated for Sambits[0] for example :

Code:
FTCPE_SAMBits0: FTCPE port map (SAMBits(0),SAMBits_T(0),SAMBits_C(0),SAMBits_CLR(0),SAMBits_PRE(0));
SAMBits_T(0) <= ((Reset AND SAMBits(0))
	OR (NOT Addr(4) AND NOT Addr(2) AND NOT Addr(3) AND NOT Addr(1) AND 
	NOT Addr(5) AND SAMBits(0)));
SAMBits_C(0) <= (Addr(9) AND Addr(8) AND Addr(15) AND Addr(14) AND 
	Addr(13) AND Addr(12) AND Addr(11) AND Addr(10) AND Addr(6) AND 
	Addr(7) AND NOT Addr(5));
SAMBits_CLR(0) <= (NOT Addr(4) AND NOT Addr(2) AND NOT Addr(3) AND NOT Addr(1) AND 
	NOT Addr(0) AND NOT Addr(5) AND NOT Reset);
SAMBits_PRE(0) <= (NOT Addr(4) AND NOT Addr(2) AND NOT Addr(3) AND NOT Addr(1) AND 
	Addr(0) AND NOT Addr(5) AND NOT Reset);

Anyone have any idea how I can do what I want? Or why the above is not working?

Cheers.

Phill.
 

So is that right, you are only supposed to assign SAMbits during a reset? That just seems counter intuitive.

I also think it's wrong from your description and basically shows what bad coding style can lead you to. You have way too many lines with single keywords that makes it harder to read or notice mistakes like putting the code you want to occur when out of reset in the reset branch.

Either get rid of all begin-end pairs unless required or compress them on a single line so they don't make the code harder to read and easier to leave out a begin or end somewhere, e.g.

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// format like this
if (!Reset) begin
  // reset value
end else begin
  case (Addr[5:1])
    // case items...
  endcase
end
 
// or like this
if (!Reset) // reset value
else case (Addr[5:1])
       // case items...
     endcase

 

Code:
always @(posedge SAMBitsAddr or negedge Reset)

accessing multiple addresses in this memory range will not trigger SAMBitsAddr unless Addr changes to some other value.

It has 16 programable bits that are programmed by writing to a pair of addresses

SAMBitsWr is not used in your design. Perhaps you
 

Hi,

Normally, you wouldn't add so much of logic to the reset condition in RTL and you wouldn't use the sequential clocking block always @ (posedge or negedge) for signals other than clocks and resets. If you want to sample the address pins , assign the incoming address to a register on the rising edge of clock and then in an always_comb block you can check for the Address[5:1].

I wouldn't use a case or any other logic inside the reset condition as it will lead to the tool inferring incorrectly, as in your case, FTCPE instead of normal Flops and logic. The reset if always used to clear registers and set them to known states so that all signals and registers are Zero'ed out and do not have X.

Hopefully, the incoming Addr is also being initialized to a known value during Reset, else you will have unknown data in you SAM registers. Moreover, you want to compare the 4-bits of Addr , but your case statement is using 5 bits [5:1], shouldn't it be [4:1] ? Your case statement may lead to latch inference or may get trimmed out during synthesis & optimization since you have not used the 5-th bit in the comparison.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top