+ Post New Thread
Results 1 to 4 of 4
  1. #1
    Newbie level 1
    Points: 16, Level: 1

    Join Date
    Mar 2017
    0 / 0

    Problems with Verilog bit array.....

    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

    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)
    	  if (!Reset)
    	    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];
    	    SAMBits[15:0] <= 0;
    	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} :
    	assign 	Data					= (DragonIORD | AVRStatusRD | RamCTRLRD | SAMBitsRD | PIACS) ? DragonDataOut : 8'bz;
    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 :

    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?



    •   Alt20th March 2017, 02:23



  2. #2
    Super Moderator
    Points: 28,167, Level: 40
    ads-ee's Avatar
    Join Date
    Sep 2013
    1559 / 1559

    Re: Problems with Verilog bit array.....

    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.
    // format like this
    if (!Reset) begin
    // reset value
    end else begin
    case (Addr[5:1])
    // case items...

    // or like this
    if (!Reset) // reset value
    else case (Addr[5:1])
    // case items...

    •   Alt20th March 2017, 16:31



  3. #3
    Advanced Member level 3
    Points: 4,949, Level: 16

    Join Date
    Feb 2015
    237 / 237

    Re: Problems with Verilog bit array.....

    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

    •   Alt21st March 2017, 03:41



  4. #4
    Full Member level 4
    Points: 3,763, Level: 14

    Join Date
    Nov 2005
    49 / 49

    Re: Problems with Verilog bit array.....


    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.

--[[ ]]--